公开记录
软件健康报告模式 0.27.0 · 指标 1.13.0 · 2026-07-23 17:24 UTC

Curviate / curviate-sdk

TypeScript SDK for the Curviate API

TypeScriptMIT★ 0 星标⑂ 0 复刻始于 2026年6月在 GitHub 上查看 ↗

Curviate/curviate-sdk 的健康指数为 100 分中的 41 分,处于「存在风险」区间。 其得分最高的类别是Vitality(75/100),最低的是Community & Adoption(24/100)。 最近一次更新在 5 天前。 近期的大部分工作由 1 位贡献者完成。

41
总分 / 100
存在风险

软件健康指数

指标归入加权类别,统一采用 1–100 量表。总体分先取类别加权平均;当公开证据触发高风险司法辖区政策时,评级会按政策调整,并设置 49(有风险)的上限。AI 就绪度不计入总体分。

41
优秀85-100堪称典范;基本满足所有检验标准
良好70-84健康;仅有轻微不足
中等50-69可接受,但存在明显不足;建议进行审查
存在风险30-49存在重大薄弱环节;采用时应保持审慎
危急1-29问题严重(项目被弃置、仅有单一维护者、缺乏基本工程规范)
活力社区与采用可持续性与治理工程质量安全AI 就绪度

评分画像

每条轴代表一个类别。形状比平均值更重要——健康的对象会填满整个图形,而“一峰一谷”式画像意味着某一维度的优势正掩盖另一维度的风险。

所有权

Curviate组织
0 关注者3 个公开仓库始于 2026年6月

该仓库由组织支持——共同承担、可问责的托管责任,可延续于任何单一维护者之后。

软件包生态系统

注册表软件包版本月下载量版本数最近发布
npm@curviate/sdk指向其他仓库——不计分0.18.14,056245 天前

按类别列示的指标

活力

项目是否仍有生命——是否仍在编写代码,是否仍在发布版本?

75良好 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 5 天前
3.5/36提交节奏 — 52 周中有 5 周有提交
18/18提交量 — 最近一年 125 次提交
0/10OpenSSF Scorecard:Maintained — project was created within the last 90 days. Please review its contents carefully
所用输入
commits_last_year125
human_commit_share1
days_since_last_push5
active_weeks_last_year5

发布纪律

100优秀
评分方式
27/27有发布版本 — 已发布 12 个发布版本
36/36发布时效 — 最近一次发布版本于 6 天前
27/27发布节奏 — 约每 2 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — 无数据
所用输入
releases_count12
latest_release_tagsdk-v0.17.0
releases_from_tags
days_since_latest_release6
mean_days_between_releases2
已排除计分(无数据或不适用):OpenSSF Scorecard:Signed-Releases。 其余权重已重新归一化。

社区与采用

项目是否拥有用户、下载量与关注度,并具备欢迎贡献者参与的配置?

24危急 · 占总体的 18%
评分方式
0/60星标 — 0 个星标
0/25复刻 — 0 个复刻
0/15关注者 — 0 位关注者
所用输入
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

社区健康

50中等
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(MIT)
0/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
has_contributing
has_issue_template
has_code_of_conduct
has_pull_request_template

可持续性与治理

项目能否在其成员之外延续——巴士系数、响应能力、由谁支持,以及软件包的维护状况?

39存在风险 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
1.8/22.5提交分布 — 头号贡献者编写了 92% 的提交
2.7/13.5贡献者广度 — 2 位贡献者
0/10OpenSSF Scorecard:Contributors — project has 0 contributing companies or organizations -- score normalized to 0
所用输入
bus_factor1
contributors_sampled2
top_contributor_share0.92
评分方式
0/46.8议题解决 — 没有议题或无数据
38.2/38.3PR 接受 — 已裁定的 PR 中 11/11 已合并
0/15OpenSSF Scorecard:Code-Review — Found 0/7 approved changesets -- score normalized to 0
所用输入
merged_prs11
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
已排除计分(无数据或不适用):议题解决。 其余权重已重新归一化。
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
0/25所有者影响力 — Curviate 有 0 位关注者
4.6/25既往记录 — 3 个公开仓库,账户约 0 年
所用输入
followers0
owner_typeOrganization
is_verified
owner_loginCurviate
public_repos3
account_age_days32

工程质量

基础的工程与文档实践是否到位?

34存在风险 · 占总体的 20%

工程实践

24危急
评分方式
0/24CI 工作流
24/24存在测试
0/16Linter 配置
0/9.6Pre-commit 钩子
0/6.4.editorconfig
0/20OpenSSF Scorecard:CI-Tests — 0 out of 3 merged PRs checked by a CI test -- score normalized to 0
所用输入
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_config

文档

50中等
评分方式
30/30README
0/25文档目录
0/15文档 / 主页站点
10/10仓库描述
0/10主题标签
10/10Wiki
所用输入
topics
has_wiki
homepage
has_readme
has_docs_dir
has_description

安全

可见的安全与供应链实践是否稳固,且不存在未解决的高风险司法辖区暴露?

25危急 · 占总体的 16%

安全态势

25危急
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — 0 out of 3 merged PRs checked by a CI test -- score normalized to 0
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/7 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
0/10Dangerous-Workflow — 无数据
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — 无数据
0/5Pinned-Dependencies — 无数据
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — 无数据
0/7.5Token-Permissions — 无数据
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated13
scorecard_versionv5.5.0
checks_inconclusive5
scorecard_aggregate2.5
已排除计分(无数据或不适用):dangerous_workflow, packaging, pinned_dependencies, signed_releases, token_permissions。 其余权重已重新归一化。

AI 就绪度

该仓库在多大程度上具备与 AI 编码代理协同开发与维护的条件?这是一枚独立的实验性徽章——权重为 0.0,因此单独呈现,不影响总体健康评分。

48存在风险 · 占总体的 0%
评分方式
0/45代理指令 — 没有 CLAUDE.md / AGENTS.md / 编辑器规则
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 100 次人类提交中有 100 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share1
agent_instruction_files
agent_instruction_max_bytes
评分方式
0/18一条命令的引导启动
22/22自动化测试
0/11Lint / 格式化配置
11/11静态类型检查 — tsconfig.json
0/10可复现环境
0/10已体现的代理实践 — 最近 100 次提交中没有代理编写的提交
0/8自动化维护 — 未观察到自动依赖更新
0/10OpenSSF Scorecard:Pinned-Dependencies — 无数据
所用输入
has_nix
has_tests
lockfiles
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configstsconfig.json
agent_commit_share0
toolchain_manifests
dependency_bot_commit_share0
已排除计分(无数据或不适用):OpenSSF Scorecard:Pinned-Dependencies。 其余权重已重新归一化。
评分方式
45/45可类型检查的代码 — TypeScript(静态类型)
54.1/55可控的文件大小 — 采样的 63 个源文件中有 1 个超过 60KB
所用输入
primary_languageTypeScript
largest_source_bytes79,415
source_files_sampled63
oversized_source_files1

机器可读接口

40存在风险
评分方式
40/40API 模式(OpenAPI/GraphQL/proto) — fixtures/openapi.json
0/20MCP 服务器
0/40可运行示例
所用输入
example_dirs
has_mcp_signal
api_schema_filesfixtures/openapi.json

关键数据

0GitHub 星标
2贡献者
125最近 12 个月提交数
5距最近推送天数
12发布版本数
1巴士系数(bus factor)
0开放议题
npm软件包生态系统数

数据采集警告

  • npm package '@curviate/sdk' points at a different repository (https://github.com/curviate/sdk); excluded from ecosystem scoring
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index npm:@curviate/sdk@0.18.1; advisories assessed against the repository dependency graph instead

更多细节

OpenSSF Scorecard 2.5 / 10
2.5综合

来自开源项目 OpenSSF Scorecard 的独立、工具无关的安全评估。每项检查奖励的是安全实践本身,而非特定供应商的工具。Scorecard 无法判定的检查项标记为 不适用,并从安全评分中剔除(绝不按零分计)。Scorecard v5.5.0 · 2026-07-23 17:24 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
0CI-Tests0 out of 3 merged PRs checked by a CI test -- score normalized to 0
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/7 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
不适用Dangerous-Workflowno workflows found
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
不适用Packagingpackaging workflow not detected
不适用Pinned-Dependenciesno dependencies found
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
不适用Signed-Releasesno releases found
不适用Token-PermissionsNo tokens found
10Vulnerabilities0 existing vulnerabilities detected
直接依赖 1
注册表软件包版本约束清单文件
npmzod^3.25.17package.json
全部依赖 未采集

本报告未能采集到解析后的依赖集合:GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 1611,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "JavaScript": 16865,
        "TypeScript": 1775426
      },
      "pushed_at": "2026-07-18T15:13:56Z",
      "created_at": "2026-06-21T16:13:28Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-18T15:14:00Z",
      "description": "TypeScript SDK for the Curviate API",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "Organization",
      "login": "Curviate",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/295625820?v=4",
      "created_at": "2026-06-21T16:02:17Z",
      "is_verified": null,
      "public_repos": 3,
      "account_age_days": 32
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "sdk-v0.17.0",
          "kind": "other",
          "published_at": "2026-07-17T16:40:43Z"
        },
        {
          "tag": "sdk-v0.16.0",
          "kind": "other",
          "published_at": "2026-07-17T09:11:23Z"
        },
        {
          "tag": "v0.15.0",
          "kind": "minor",
          "published_at": "2026-07-11T11:03:41Z"
        },
        {
          "tag": "v0.14.1",
          "kind": "patch",
          "published_at": "2026-07-07T03:28:15Z"
        },
        {
          "tag": "v0.14.0",
          "kind": "minor",
          "published_at": "2026-07-07T02:58:11Z"
        },
        {
          "tag": "v0.13.0",
          "kind": "minor",
          "published_at": "2026-07-06T14:56:08Z"
        },
        {
          "tag": "sdk-v0.12.0",
          "kind": "other",
          "published_at": "2026-07-05T06:10:22Z"
        },
        {
          "tag": "sdk-v0.11.0",
          "kind": "other",
          "published_at": "2026-07-04T18:49:12Z"
        },
        {
          "tag": "sdk-v0.10.0",
          "kind": "other",
          "published_at": "2026-07-03T20:09:29Z"
        },
        {
          "tag": "sdk-v0.2.1",
          "kind": "other",
          "published_at": "2026-06-29T11:44:52Z"
        },
        {
          "tag": "sdk-v0.2.0",
          "kind": "other",
          "published_at": "2026-06-28T17:18:09Z"
        },
        {
          "tag": "v0.1.1",
          "kind": "patch",
          "published_at": "2026-06-22T18:17:52Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "5855d2d476aee0212348d33509248591f132edea",
          "body": null,
          "is_bot": false,
          "headline": "chore: update repo URLs after rename",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-18T15:13:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "feef41ed082ec99e8c97e7b34a3aa75f2daccfc8",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): @curviate/sdk 0.18.1",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-18T10:05:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ef7982802f52322d9855c292695bd7b919c5aa0",
          "body": "The company reply endpoint now accepts the same 2-… conversation id that\ncompanies.chats()/searchChats() return and resolves the page mailbox\ninternally from the identifier. Drop the send-ready COMPANY_ chat-id\nrequirement and the inboxes.listChats() sourcing from the class + method\nJSDoc and the example; add an Unreleased CHANGELOG entry. Method signature\nand response shape are unchanged (documentation only).\n\nCo-authored-by: Raphael Redmer <ra.redmer@outlook.com>",
          "is_bot": false,
          "headline": "docs(companies): sendMessage takes the normal 2-… chat id (#11)",
          "author_name": "Raphael",
          "author_login": "rapha-red",
          "committed_at": "2026-07-18T09:57:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9d0c226735db61e20e768df125b9a64ee508caf4",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): @curviate/sdk 0.18.0",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-17T21:17:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3e177b30fa50321bb1388d80ea03b47d8c3db2c7",
          "body": "…/029)\n\nPOST /v1/{account_id}/companies/{identifier}/chats/{chat_id}/messages —\nreply to a company-inbox conversation as the page. chatId must be the\nsend-ready COMPANY_ id from inboxes.listChats(), not the 2-… id\ncompanies.chats()/chat()/searchChats() return; reply-only. Result\ncarries sent_as, the\n[…]\ni.json + src/generated/types.ts off the\nfeat/company-chat-reply server branch (also picks up the Messaging:\nInboxes tag flatten, api/029 FR-006). Parity pin +1 (145 methods);\npath-grammar bank +1 row.",
          "is_bot": false,
          "headline": "feat(companies): add sendMessage (reply as the company page, spec api…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-17T19:05:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4c70bddd8835586bc910df2e40211d80d1cb0f36",
          "body": "companies.followInvite + release 0.17.0",
          "is_bot": false,
          "headline": "Merge pull request #10 from Curviate/feat/company-follow-invite",
          "author_name": "Raphael",
          "author_login": "rapha-red",
          "committed_at": "2026-07-17T16:38:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f1930b9a3c6299b1cfd820c7156b6f9c02db0994",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): @curviate/sdk 0.17.0",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-17T16:37:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "19efb7f290085d777193f606b3b13fe9a393fc28",
          "body": "…ak-scan)",
          "is_bot": false,
          "headline": "chore(companies): drop internal spec refs from follow-invite copy (le…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-17T16:37:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3f120ef34ad84682a7a7cc79c6593faaf09d4001",
          "body": "… success)\n\nqa live-verify proved the substrate top-level-rejects a batch containing any\ninvalid/nonexistent invitee (404 RESOURCE_NOT_FOUND); only an all-valid batch\nreturns 200 with per-invitee results (server commit c2dcd451). Reconcile the\nSDK side:\n\n- JSDoc: reword to the all-or-nothing contrac\n[…]\nurviateError(RESOURCE_NOT_FOUND), not a 200.\n- Re-dump fixtures/openapi.json off the corrected server + regenerate\n  types.ts; only the follow-invite path changes.\n- CHANGELOG entry reworded to match.",
          "is_bot": false,
          "headline": "fix(companies): reconcile followInvite to all-or-nothing (not partial…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-17T13:58:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c82bd786373ddd04d048cb9b98f31c3239875a6d",
          "body": "Re-dump the feat-branch server OpenAPI (server commit 53183f2b dropped em\ndashes from the follow-invite endpoint/param/response descriptions) and\nregenerate types.ts. Only the follow-invite path entry changes; every other\npath is byte-identical. One pre-existing, out-of-scope em dash remains on\nthe shared company sub-resource identifier param description (used by 10+\nother company endpoints, not touched by 53183f2b).",
          "is_bot": false,
          "headline": "fix(companies): drop em dashes from follow-invite OpenAPI snapshot",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-17T12:31:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bc054e75446c2303771ef101e68d2824d5804510",
          "body": "Extend the companies resource with followInvite(identifier, body) —\nPOST /v1/{account_id}/companies/{identifier}/follow-invite — modeled on\ninvites.send. Invites the connected account's 1st-degree connections to\nfollow an administered page; partial-success results, one outcome per\ninvitee in request\n[…]\n.json + src/generated/types.ts off the\nfeat-branch server snapshot (adds the new path only, byte-identical\notherwise). Update the parity pin (+1 companies method, 144 total) and\npath-grammar coverage.",
          "is_bot": false,
          "headline": "feat(companies): add followInvite (spec api/028 FR-003)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-17T12:18:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "10397297cf8398a8807820ef8c23e680b7041f07",
          "body": "feat: inboxes resource, sent_as, requested_products; remove disabled_features (0.16.0)",
          "is_bot": false,
          "headline": "Merge pull request #9 from Curviate/feat/company-scope-surface",
          "author_name": "Raphael",
          "author_login": "rapha-red",
          "committed_at": "2026-07-17T09:09:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f4fc087439b076cf357afa716eba0f97c00928e4",
          "body": "Founder follow-up: the company-behalf send must be first-class on the SEND\nmethod's own doc, not only on the inboxes resource that discovers a\nCOMPANY_ chat id.\n\n- messaging.sendMessage(): added an explicit \"Sending on behalf of a\n  company page\" paragraph (no separate method, pass a COMPANY_ chat i\n[…]\ned in README.md and used by the tool's own\n  auto-synthesized examples elsewhere.\n\nNo API shape change, documentation only (stays 0.16.0 pre-publish).\n\ntypecheck/test(514)/check:clean/build all green.",
          "is_bot": false,
          "headline": "docs: document company-behalf send explicitly on sendMessage itself",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-17T08:28:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "83f7708ab4ebcd6957204063448da0d12aa2561a",
          "body": "No API shape change, documentation and ergonomics only (version stays\n0.16.0 pre-publish).\n\n- inboxes.ts: rewrote the module and method doc comments around the\n  three-step reply-as-a-page pattern (list -> listChats -> sendMessage),\n  spelled out explicitly rather than left implicit. list()'s exampl\n[…]\ncs.ts extracts it into the public docs site). Pre-existing prose\nelsewhere in these files (and in README.md) is untouched, out of scope for\nthis pass.\n\ntypecheck/test(514)/check:clean/build all green.",
          "is_bot": false,
          "headline": "docs: enrich inboxes/sent_as JSDoc with the full reply-as-page flow",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-17T07:59:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "61983912b970328aacd55de9a8ab31b7a8b0c39b",
          "body": "…; PREMIUM_CONFLICT/REAUTH_REQUIRED codes (0.16.0)\n\nNew account-scoped `inboxes` namespace (2 methods, Beta), following the\nexisting resource pattern: `list(query?)` discovers the account's personal\ninbox plus, when the company product is attached, one entry per company\npage x folder; `listChats(inb\n[…]\npre-1.0 breaking release, matching the\n0.14.1 -> 0.15.0 precedent). Not published — publish is a separate,\nfounder-gated step.\n\ntypecheck/test(514)/check:types/check:clean/build/verify:dist all green.",
          "is_bot": false,
          "headline": "feat(inboxes): add inboxes namespace; sent_as/requested_products docs…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-16T23:01:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "272df4764b317c888c687fe54e22ec9bfe807427",
          "body": "Regenerated from the running trunk server's live OpenAPI document\n(/.well-known/openapi.json, fake substrate lane) to pick up the WP4\ncompany-scope cascade: the two new Messaging: Inboxes endpoints\n(GET /v1/{account_id}/inboxes, GET /v1/{account_id}/inboxes/{inbox_id}/chats,\nboth Beta), the additive\n[…]\nations\naccount for the delta. No other schema components added or removed.\n\nsrc/generated/types.ts regenerated to match via `pnpm gen:types:fixture`.\n\ntypecheck/test/check:types/check:clean all green.",
          "is_bot": false,
          "headline": "chore(fixtures): refresh openapi.json + regen generated types",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-16T23:01:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7ac33509c4a0cfb9bd5aaa96ccd8050282b4b8e6",
          "body": "Fixture had drifted from the served surface across two prior server-side\npasses (deliberately not pulled in surgically at the time): post-id path\nparams on the comment/reaction endpoints now document the opaque get-post/\nlist-posts id as the only accepted form (share URLs/URNs/bare numeric ids\ndropp\n[…]\n?: string` to\n`cursor: string | null`, which the shared PageEnvelope pagination type\nalready declared as `string | null` so no consumer breaks.\n\ntypecheck/test/build/check:types/check:clean all green.",
          "is_bot": false,
          "headline": "chore(fixtures): refresh openapi.json + regen generated types",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-16T17:42:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7306c6c11f2c9793c8f3ea6bbbc6dbcd57b877f2",
          "body": "… returns\n\nchats/search reused the shared full-chat schema, but the mapper backing it\nis strictly sparser (no user{}, last_message never carries timestamp/\nis_sender). Regenerated from the corrected served OpenAPI document — types\nnow match the wire, not the shared shape.",
          "is_bot": false,
          "headline": "fix(types): searchChats item schema narrows to what the wire actually…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-16T12:29:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "648445e395a44f5c19a5752140d1e8af2ab21c3d",
          "body": "…scan)",
          "is_bot": false,
          "headline": "chore(tests): strip internal doc references from test comments (leak-…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T20:09:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "74c45e3c204a1c1ac41d444bdaa8b07446636aa2",
          "body": "New notifications namespace on client.account(id).notifications — the\nconnected account's own notification centre (api/019):\n\n- list(query?) -> GET /v1/{account_id}/notifications — cards newest-first,\n  plus the account-level unread_count/latest_published_at alongside the page.\n- delete(cardUrn) -> \n[…]\n: parity pin 141 methods across 17\nnamespaces (was 138/16 after the prior posts commit; 135/16 baseline before\nthis feature slice — accounts(4)+auth(5)+webhooks(6) root, 14 account-scoped\nnamespaces).",
          "is_bot": false,
          "headline": "feat(notifications): add NEW account-scoped notifications namespace",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T20:07:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "795b8ff4651645d05190d790128a6d99d3e3e13d",
          "body": "Extends the posts resource with the saved-posts bookmark surface (api/023):\n\n- listSaved(query?) -> GET /v1/{account_id}/saved-posts — the connected\n  account's own saved posts, a self resource (no {user_id}). Items are\n  previews only (snippet capped at <=140 chars) — never the full post body.\n- sa\n[…]\nunsaving re-asserts the same state).\n\nposts is now 12 methods (was 9). Parity pin: 138 methods across 16 namespaces\n(was 135/16) — notifications lands in the next commit for the campaign-final\n141/17.",
          "is_bot": false,
          "headline": "feat(posts): add saved-posts methods (listSaved/save/unsave)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T20:06:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "57370d5663846b6abfd3e78cb19d5311f1ca8b1a",
          "body": "Documents the 12 additive methods landed across the three preceding\ncommits: companies +8 (company-insights trio + Beta company-inbox\nquintet), search +3 (groups/services/getServiceParameters), messaging +1\n(searchChats). Nothing removed, renamed, or reshaped.",
          "is_bot": false,
          "headline": "docs(changelog): note the companies/search/messaging extensions (M2/F2)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T19:50:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fb8d6521265455ee6f21859a46ebf09257d9e0f5",
          "body": "Adds messaging.searchChats(params), mirroring listChats:\nGET /v1/{account_id}/chats/search. Free-text searches the account's own\ninbox (participant names and message content) -- distinct from the new\ncompanies.searchChats, which searches a company page's admin inbox.\n\nmessaging is now 13 methods (was 12). Parity pin 134->135 methods / 16\nnamespaces -- the final M2/F2 aggregate (companies +8, search +3,\nmessaging +1 = +12 total, 123->135).",
          "is_bot": false,
          "headline": "feat(messaging): add searchChats method",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T19:50:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b171d4406ba990b1c106a2dd8fa0eac607f01ac8",
          "body": "Extends the search resource with 3 account-scoped methods, mirroring the\nexisting getParameters/people naming:\n\n- groups(query) -> GET /v1/{account_id}/search/groups\n- services(body & query) -> POST /v1/{account_id}/search/services (body +\n  query merged, as people/companies already are)\n- getServic\n[…]\nice-category/location terms into the opaque\n  ids services() accepts\n\nsearch is now 9 methods (was 6). Parity pin 131->134 methods / 16\nnamespaces (intermediate; F2 lands 135/16 once messaging lands).",
          "is_bot": false,
          "headline": "feat(search): add groups, services, and service-parameters methods",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T19:49:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d7c5da194522cf239e3bd9eddb897dcd858cba90",
          "body": "Extends the companies resource with 8 account-scoped methods:\n\n- managed(query?) -> GET /v1/{account_id}/companies/managed\n- followers(identifier, query?) -> GET .../companies/{identifier}/followers\n  (re-added under a different item shape than the pre-0.15.0 method of the\n  same name -- company_fol\n[…]\nror block + absent-list entry, companies.test.ts's removal\ndescribe block) to positive coverage. Parity pin 123->131 methods / 16\nnamespaces (intermediate; F2 lands 135/16 once search/messaging land).",
          "is_bot": false,
          "headline": "feat(companies): add company-insights + Beta company-inbox methods",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T19:48:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bd0097c63754c0fb31f2fc505218b4679a220041",
          "body": "…/F1)\n\nUnreleased section documenting the three new account-scoped read namespaces\n(8 methods total); additive and non-breaking. F2/F3 extend this section.",
          "is_bot": false,
          "headline": "docs(changelog): note the additive profile/groups/feed namespaces (M2…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T19:30:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb4eeff4a25f78daf33015737f57e6b53ebf58be",
          "body": "New feed namespace on client.account(id).feed — home() reads the connected\naccount's LinkedIn home feed as agent-actionable posts (api/019 FR-001), two\nsort orders on one endpoint, unbounded cursor-walked stream. Account-scoped\nonly. Completes M2/F1: parity pin 122->123 methods / 15->16 namespaces (F1\nfinal; notifications/saved-posts/companies-followers land in F2/F3).",
          "is_bot": false,
          "headline": "feat(feed): add account-scoped feed namespace (home read)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T19:28:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1c22c6b055fa28652e8ae3d0e9e9c48121195094",
          "body": "New groups namespace on client.account(id).groups — list (own groups, or\nanother member's via {profile}), get (single group detail), members (roster,\nwith the folded-in {name} search) — per api/022. Account-scoped only; group\nids interpolate into the path leading with account_id. Parity pin 119->122\nmethods / 14->15 namespaces (intermediate; F1 lands 123/16).",
          "is_bot": false,
          "headline": "feat(groups): add account-scoped groups namespace (3 methods)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T19:24:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ea0e7f6b72c7ee922b2d5e3fda818a96867c3de2",
          "body": "New profile namespace on client.account(id).profile — subscription,\nanalytics, visitors, ssi — each a self-read of the connected account's own\nLinkedIn insight surface (api/017). Account-scoped only, mirroring\ncompanies/users; never mounted on the root client. Types alias off the\nregenerated OpenAPI snapshot. Parity pin 115->119 methods / 13->14 namespaces\n(intermediate; F1 lands 123/16).",
          "is_bot": false,
          "headline": "feat(profile): add account-scoped profile insights namespace (4 methods)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T19:21:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "858f8da417bf7274419cbb124df2b00351d2a0db",
          "body": "…ints\n\nRe-snapshot fixtures/openapi.json from the served spec (90->115 paths,\n115->141 operations) and regenerate src/generated/types.ts. Adds the paths\nfor the M2 profile/groups/feed/notifications/companies/search/messaging/posts\nsurfaces; resource classes for the first three namespaces follow. check:types\ngreen; vendor-name grep clean.",
          "is_bot": false,
          "headline": "chore(types): refresh OpenAPI fixture + regenerate types for M2 endpo…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-15T19:17:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b3c747ab90c4005f17f832cb6739eefcedf34386",
          "body": "check:clean previously scanned files by extension only, which silently\nskipped extensionless dotfiles like .gitignore. Extend the scanner to\nalso match a fixed dotfile allowlist so a leaked internal reference in\none of these files gets caught going forward.\n\nAlso reword the .gitignore comment explaining why the generated types\nare committed, dropping an internal reference that had slipped into\npublic view.",
          "is_bot": false,
          "headline": "chore(hygiene): scan dotfiles in check-clean; reword .gitignore comment",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-13T11:08:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a0dd1d65f464062493d006f76d08ddce3caa6442",
          "body": "Co-authored-by: Raphael Redmer <ra.redmer@outlook.com>",
          "is_bot": false,
          "headline": "revert: drop unused RATE_LIMIT_INGRESS error code (#8)",
          "author_name": "Raphael",
          "author_login": "rapha-red",
          "committed_at": "2026-07-12T17:37:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dcc09fd0bc2e4054a5e7cc1cb8fde3eee7baaf87",
          "body": "Co-authored-by: Raphael Redmer <ra.redmer@outlook.com>",
          "is_bot": false,
          "headline": "feat: add RATE_LIMIT_INGRESS error code (#7)",
          "author_name": "Raphael",
          "author_login": "rapha-red",
          "committed_at": "2026-07-12T15:00:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cea5862e162750032625f3bae43e8a291a75bc83",
          "body": "…15.0",
          "is_bot": false,
          "headline": "docs(changelog): note the users.update description-strip fix under 0.…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T10:48:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "85b61cd466b08accb97589480cc78ddfcad42407",
          "body": "UserUpdateBody never declared description, so a typed caller was already\nrejected at compile time — but an untyped/JS caller (or an as-cast) could\nstill put it on the object, and update() forwarded the body verbatim with\nno runtime check. Strip description from the outgoing payload before the\nreques\n[…]\ner the strip existed. It now sends a raw, untyped object literal\ncarrying description alongside legitimate keys and asserts the captured\nrequest body omits it while still carrying the legitimate keys.",
          "is_bot": false,
          "headline": "fix(users): strip a smuggled description key from update() at runtime",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T10:48:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "770b6e56410d53e190c68195d7ba1c1167d7626d",
          "body": null,
          "is_bot": false,
          "headline": "docs(changelog): note the RATE_LIMITED decode fix under 0.15.0",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T08:58:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6f8df44757adda7a4bfce5a13816fe0c3aa98bae",
          "body": "RequiredTier (errors.ts) and the transport's local REQUIRED_TIERS runtime\nset (transport.ts) were a hand-mirrored union+Set pair, identical today\nbut able to silently drift apart — the same class of bug ERROR_CODES /\nKNOWN_ERROR_CODES already closed off. Introduces REQUIRED_TIERS as the\nsingle sourc\n[…]\nD_TIERS\n(exported from errors.ts, replacing transport.ts's private copy) are both\nderived from it. Pure refactor — the four tier values are unchanged, and\nthe public RequiredTier export is unaffected.",
          "is_bot": false,
          "headline": "refactor(errors): derive RequiredTier from a single-source array",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T08:58:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c0048f23892b669b34584fe9678766391999230f",
          "body": "The 429 the Recruiter and Sales Navigator read surface returns under\nLinkedIn-platform throttling (dedicated RateLimit-Policy / RateLimit /\nRetry-After response headers, retry_likely_to_succeed: true) is a real,\ndocumented error code — deliberately self-referenced in the served docs\nthe same way ACC\n[…]\nf\nevery error code the served OpenAPI document self-documents, so a future\nserver code that reaches the public docs fails the SDK suite until the\ntaxonomy learns it — the same class of gap this fixes.",
          "is_bot": false,
          "headline": "fix(errors): decode RATE_LIMITED instead of downgrading to INTERNAL",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T08:57:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5fe2668dbb53c525fa29b27dadc3f85a2abbac1b",
          "body": "Fixture was pinned to a stale served surface. Refreshed from the live\nstaging document (path/op counts unchanged at 90/115): the following-op\ngained a 422 LINKEDIN_OPERATION_NOT_SUPPORTED example and a self-only\nuser_id description, the user-profile op's skills-section items now\ndocument endorsement\n[…]\n the\nendorse-skill op's description states the same precondition. Purely\nadditive description/example text plus a widened (non-breaking) skills\nitem shape — no path, method, or request-schema changes.",
          "is_bot": false,
          "headline": "chore(sdk): refresh OpenAPI fixture + regen generated types",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T08:38:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "40496deca483c372113f94e64e49e63e3d9bf133",
          "body": "…r 0.15.0",
          "is_bot": false,
          "headline": "docs(changelog): note the CONNECTION_REQUEST_CONFLICT decode fix unde…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T08:28:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0dd3580c33123ccb2cecb4aa802eb6c976535489",
          "body": "…g to INTERNAL\n\nThe runtime error-code set and the ErrorCode type were maintained as two\nindependent hand-written lists. CONNECTION_REQUEST_CONFLICT — a real 409 the\nAPI returns when a connect-request to a member already exists — was in\nneither, so the transport silently downgraded it to INTERNAL. E\n[…]\nver drift again. Add exhaustive per-code decode coverage, an\nexplicit CONNECTION_REQUEST_CONFLICT round-trip test, an unknown-code negative\ncontrol, and a compile-time lock on the type/array equality.",
          "is_bot": false,
          "headline": "fix(errors): decode CONNECTION_REQUEST_CONFLICT instead of downgradin…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T08:26:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f119bd859e3a41199e417c8ecf9db87f5cb9bbda",
          "body": "Server ships this 422 for a permanent LinkedIn platform limitation on\nthe attempted operation (e.g. listing a non-self user's following\nlist) — user-fixable is false in the sense the operation can't be\nretried into success, so retry_likely_to_succeed is false. Added to\nthe ErrorCode union and the transport's known-code set so it decodes\nto its own code instead of falling back to the retryable INTERNAL.",
          "is_bot": false,
          "headline": "feat(errors): add LINKEDIN_OPERATION_NOT_SUPPORTED error code",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T06:59:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "508afc0aada9163d820d3f84f02565eb86a922d6",
          "body": "accounts.link -> auth.intent (prose), profiles.get -> users.get('me'/id),\ndrop an unverifiable field from the pagination example, bump status to 0.15.0.",
          "is_bot": false,
          "headline": "docs(sdk): realign README examples to the v2 users/auth surface",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T00:05:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "008dfb05faa1db09c0916da4bc7ede444a87e331",
          "body": "Document every breaking category — 14 removals, 3 namespace renames/splits, 11\nmethod rename/relocations, the 6 stale-shape + new write-body reshapes, and the\naccount-first path-grammar migration — plus the new surface (comments, jobs\nwrites, project-centric recruiter, follow/update/markChatRead/fromUrl/delete).\nStage package version at 0.15.0 (not published).",
          "is_bot": false,
          "headline": "docs(sdk): changelog 0.15.0 v2-parity; stage version 0.15.0",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T00:03:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c33349ac3ecc46bfea6b73beadb9d72c9a3982e1",
          "body": "…ces)\n\nTable-driven set-equality per namespace (extra/missing method fails by name),\nroot/account mounting guards, total==115, and a compile-time @ts-expect-error\nblock proving the 14 removed methods + the split respond are gone.",
          "is_bot": false,
          "headline": "test(sdk): add public-surface bijection test (115 methods, 13 namespa…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-11T00:01:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aacc1a96c73cf93806419e7d1601357d28ccb6b6",
          "body": "….getProjectJob\n\n- recruiter.listProjectJobs -> getProjectJob (op returns a single posting)\n- root client mounts exactly {accounts, auth, webhooks}; account(id) mounts the\n  10 account-scoped namespaces only. buildAccountScopedNamespaces no longer\n  leaks webhooks; add buildRootNamespaces/RootNamespaces for the root half.\n- transport: drop unused catch binding",
          "is_bot": false,
          "headline": "refactor(sdk): enforce root/account namespace split; rename recruiter…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T23:59:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2a8247e607d1f25d5a6350f2349a144f0664c892",
          "body": "Append 14 representative account-first rows for the recruiter namespace to\nthe shared table-driven grammar bank — covering every distinct path shape:\nid-GET (getProfile), POST (startChat, searchParameters — the was-GET reshape,\nsearchFromUrl), PATCH (updateProject), deep project-scoped GET/POST\n(sea\n[…]\neateProjectJob, getProjectJobBudget), the client-side\nresolved getJob, the deepest publish path, bodyless closeJob, the pipeline\ncandidate-save POST, listApplicants, and the binary downloadResume GET.",
          "is_bot": false,
          "headline": "test(resources): add recruiter rows to the path-grammar bank",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T23:50:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e3136170fe792a78ec9bba6a7f4b4788ead27d86",
          "body": "Rebuild the recruiter namespace against the v2 served surface: account-first\npath grammar (account_id is the leading /v1/ segment, never query/body), 10\nrealigns, 3 reshapes, 9 new project-centric ops. startChat is now JSON-only\n(signature + subject required, base64 attachments in-body — no multipar\n[…]\nlveJobCheckpoint; addCandidate renamed to saveCandidate.\n\nReplaces the stale test/resources.recruiter.test.ts with a per-resource\ntest/resources/recruiter.test.ts (29 wire tests, path + body + query).",
          "is_bot": false,
          "headline": "refactor(recruiter): project-centric rebuild — 23 account-first methods",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T23:48:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3558bd9d75a40edc3ee318e5970dbc1b43001d7a",
          "body": "10 methods: list, create, get (realign — account-first path, id/URL\nclient-side resolution preserved), update, getBudget, publish, close,\nlistApplicants, getApplicant, downloadResume. account_id is now the\nleading /v1/ path segment. list's state query param is required.\ncreate/update's job_title/com\n[…]\nst.ts to\ntest/resources/jobs.test.ts (established convention) with fixtures\nupdated for the new job_posting response shape (company is now an\nobject; applicants_counter renamed to applications_count).",
          "is_bot": false,
          "headline": "refactor(jobs): realign get to account-first, add 9 new methods",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T23:34:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cc45e9712eddddff8d122907c10532cf8731305e",
          "body": "listUserComments, create, edit, delete, reply, listReplies,\nlistReactions, addReaction, removeReaction. account_id is the leading\n/v1/ path segment on every request. create relocates from\nposts.comment; listUserComments relocates from profiles.listComments\n(both realigns, not new). reply shares its \n[…]\nE-with-body: DELETE .../comments/{comment_id}/reactions carries\n{reaction}, same unified lowercase enum as posts.react/unreact. Wired\ninto the namespace bag (index.ts) and the root client (client.ts).",
          "is_bot": false,
          "headline": "feat(comments): add new comments namespace (9 methods)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T23:30:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4ec271a948ff59113777499a3846504fdaf8a422",
          "body": "…chFromUrl\n\n12 methods: searchPeople, searchCompanies, getParameters, startChat,\ngetProfile, accountLists, leadLists, browseAccountList, browseLeadList,\nsaveAccount, saveLead, searchFromUrl (new — POST .../sales-navigator/search\nbody {url}). account_id is now the leading /v1/ path segment on every\nr\n[…]\nJSON objects. saveAccount /\nsaveLead bodies shrink to just their own field ({company_id} / {user_id})\nnow that account_id lives in the path, not the body. Removed: syncMessages\n(no served equivalent).",
          "is_bot": false,
          "headline": "refactor(sales-navigator): realign to account-first grammar, add sear…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T23:21:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1d3339d3d6b3ef58c44ba26e70953e315af007f2",
          "body": "9 methods: listComments, get, delete (new — bodyless, 204), create,\nlistUserPosts, listReactions, react, unreact (new — DELETE-with-body\n{reaction}), listUserReactions. account_id is now the leading /v1/ path\nsegment on every request. create drops multipart entirely — the served\nsurface has zero mul\n[…]\nnot new). The\ncomment-write surface (comment, comment editing) relocates to the\nupcoming comments namespace — listComments (a post's own comment read)\nstays here. Removed: list (no served equivalent).",
          "is_bot": false,
          "headline": "refactor(posts): realign to account-first grammar, add delete/unreact",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T23:18:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "078e001113ce2b448a6087701cb00838cac404fc",
          "body": "…line\n\n6 methods: send, listSent, listReceived, accept, decline, cancel.\naccount_id is now the leading /v1/ path segment on every request. The\nold combined respond(invitationId, {action}) splits into two dedicated,\nbodyless POSTs matching the served surface — accept and decline — each\nissuing .../invites/received/{invitation_id}/{accept|decline} with no\nrequest body. respond is removed. cancel realigns to DELETE\n.../invites/sent/{invitation_id}, also bodyless.",
          "is_bot": false,
          "headline": "refactor(invites): realign to account-first grammar, split accept/dec…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T23:08:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "649d2095e85d8f7329526db2d204bc1136596a9d",
          "body": "12 methods: listChats, startChat, getChat, markChatRead (new — PATCH\n.../chats/{chat_id} body {read}), listMessages, sendMessage, getMessage,\neditMessage, deleteMessage, addReaction, getAttachment, sendInMail.\naccount_id is now the leading /v1/ path segment on every request.\ngetMessage/editMessage/d\n[…]\nvel as base64 JSON objects, never multipart — the served\nsurface has zero multipart ops. Removed: syncChat, syncMessages (no\nserved equivalent); getInMailBalance (relocated to users.getInMailCredits).",
          "is_bot": false,
          "headline": "refactor(messaging): realign to account-first grammar, add markChatRead",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T23:08:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0339aacbe6be4cb2ffa52ac44875fdc269b5bdeb",
          "body": "6 methods: getParameters, people, companies, posts, jobs (all realigned),\nplus new fromUrl (POST /v1/{account_id}/search body {url}) — the sole\nhome of URL-mode search now that the structured endpoints no longer\naccept a url field. Pagination (offset/limit/cursor) stays a top-level\nquery param on every op, split out of the merged body+pagination\nargument on the wire. Completes the path-grammar bank and paginate\nwiring for the users/companies/search chunk.",
          "is_bot": false,
          "headline": "refactor(search): realign to account-first grammar, add fromUrl",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T22:58:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d600b2f429c6f04f6d32f58cb54cae219bafbdd2",
          "body": "4 methods: get, employees, posts, jobs. account_id moves from a query\nparam to the leading /v1/ path segment, fixing the pre-existing\ncompanies.get query-param-injection test failure. followers has no\nserved equivalent and is removed; get()'s follower_count is the\naudience-size signal that replaces it.",
          "is_bot": false,
          "headline": "refactor(companies): realign to account-first grammar, drop followers",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T22:57:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fff0e9ee4fd49ad2352e86e8103edd059e9976ad",
          "body": "…mmar\n\n9 methods: get (folds getMe via 'me' sentinel), update, listRelations,\nlistFollowers, listFollowing, follow, unfollow, getInMailCredits\n(relocated from messaging), endorseSkill (body key endorsement_id, was\nskill_endorsement_id). account_id is now the leading /v1/ path segment\non every request, never a query param.",
          "is_bot": false,
          "headline": "refactor(users): rename profiles->users, realign to account-first gra…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T22:56:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d12e9d5c02fc3d633a728b7b23da3c60ca78b6ce",
          "body": "Proves, at the resource-wrapper level, that a root-scoped method builds a URL\nwith no account segment and that account_id never leaks into the query\nstring — for accounts/auth/webhooks, the namespaces realigned so far. The\nseam itself is already proven directly against createContext in\ntest/internal\n[…]\nnner, with an inline\nexample showing the account-scoped row shape, so later resource realignments\n(messaging, users, recruiter, sales navigator, ...) append their own rows\nwithout touching the runner.",
          "is_bot": false,
          "headline": "test(resources): add the table-driven path-grammar bank",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T22:39:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5a45b97c19f99cb1cd6ba08e8a7f9b8afd2cde03",
          "body": "The 6 remaining webhooks ops (create/list/listEvents/get/update/delete) were\nalready aligned to the served snapshot; only getStateDiff had no matching\npath in the regenerated types. The whole-SDK method-count coverage test\nmoves out of this file (it now only asserts webhooks' own 6-method surface)\nsince the cross-namespace bijection is inherently a moving target until every\nnamespace realigns — a dedicated parity test picks that up.",
          "is_bot": false,
          "headline": "fix(webhooks): remove getStateDiff — no served equivalent",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T22:38:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "886f98daf690d77e07923a1821aabadee0e8591c",
          "body": "…scoped auth namespace\n\naccounts keeps its 4 aligned ops (list/get/update/disconnect). The 5\nconnect/checkpoint ops (link, solveCheckpoint, requestCheckpoint,\npollCheckpoint, getConnectSession) move to a new root-scoped auth namespace,\nre-keyed to the served /v1/auth/* paths. link and reconnect merg\n[…]\nnticates an existing\naccount in place via auth.intent({ account_id, ... }).\n\nauth is wired as root-only: buildAccountScopedNamespaces now strips both\naccounts and auth out of the account(id) accessor.",
          "is_bot": false,
          "headline": "feat(auth): split connect/checkpoint ops out of accounts into a root-…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T22:36:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "971d9eec326264112efa48d622972d34e1596f6a",
          "body": "… 115 ops)\n\nReplace `fixtures/openapi.json` with the current served OpenAPI (staging,\ndeep-equal to the live `/.well-known/openapi.json` — verified byte-for-byte),\nand regenerate `src/generated/types.ts` from it via `gen:types:fixture`. The\nfixture is written pretty-printed (`JSON.stringify(doc, nul\n[…]\naccount-first realignment owned by the later chunks. This regen\ncommit's own scope (fixture + generated types) is coherent and clean; the\npackage returns to whole-tree green when the wrappers realign.",
          "is_bot": false,
          "headline": "chore(generated): regen types from the v2 served snapshot (90 paths /…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T22:22:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "840dbd0b6a4bd0a5e8f218c41590393f76d13297",
          "body": "…seam\n\nMove `account_id` from a query/body/`none` field into the leading `/v1/`\npath segment. An account-scoped method now declares its path template with a\nliteral `{account_id}` placeholder; the bound `createContext(config, id)`\nsubstitutes the fixed id into it. Query and body are forwarded to the\n[…]\ne final chunk returns the whole package to green. This foundation\ncommit's own scope (context seam + its test) is green: targeted vitest 18/18,\ncheck:clean OK. Zero tsc errors in the foundation files.",
          "is_bot": false,
          "headline": "feat(internal): account-first path grammar; retire AccountIdLocation …",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-10T22:21:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "92780b68ea26c24a5edcb23c95459d227c5d233a",
          "body": "…nt-count description\n\nconstructEvent's JSDoc and both code examples (Express, Hono) named the\nsignature header X-Curviate-Signature; the dispatcher actually sends\nCurviate-Signature (curviate-signature on req.headers), so integrators\ncopying the examples verbatim got undefined. Also corrects the ge\n[…]\n\"default: all 11 lifecycle events\", matching the account_status catalogue\n(fixture + generated types kept in sync; check:types drift gate green).\n\n0.14.1 patch, docs-only — no runtime behavior change.",
          "is_bot": false,
          "headline": "fix(webhooks): docs patch — correct signature header name + stale eve…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-07T03:17:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7f89c16cf0583eba1d7712a71f254f33b47ecfcf",
          "body": "…0.14.0)\n\nRegenerates types.ts from the W2 OpenAPI (surgical patch, webhook paths only)\nand adds webhooks.get(id) for the net-new GET /v1/webhooks/{id}. Re-keys\nCurviateEvent 19->24 deliverable events to match the create-subscribable\ncatalogue (messaging 8, user 2, account_status 14), pinned at comp\n[…]\nerated create-variant `events`\n  enums, plus @ts-expect-error negatives for all 7 removed names.\n- Method-count coverage guard bumped 93->94.\n- README/CHANGELOG/package.json version updated to 0.14.0.",
          "is_bot": false,
          "headline": "feat(webhooks): v2 catalogue cascade — get() + CurviateEvent re-key (…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-07T00:18:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "791289551edfbe9f02995806d1047f7e0870f580",
          "body": "The server's W7 409 duplicate-connect code (accounts.link/reconnect/\nsolveCheckpoint) was missing from the hand-maintained ErrorCode union and\ntransport's KNOWN_CODES set, so toErrorCode() silently narrowed it to\nINTERNAL — which is also in RETRYABLE_CODES, so a client would retry a\nrequest that can\n[…]\n RESOURCE_ACCESS_RESTRICTED in 0.12.0.\n\nAlso notes the 422 checkpoint challenge_type (captcha | phone_register)\nas typed-generic in the changelog (documented in prose, no typed field\nyet on the wire).",
          "is_bot": false,
          "headline": "fix(errors): add ACCOUNT_ALREADY_LINKED to the ErrorCode surface",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-06T14:44:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dccff61f37d09ffc3cc90ec6a29dc1a04bca9153",
          "body": "Regenerate types from the current merged server OpenAPI (emitted locally\nfrom the worktree server) to pick up the connect-fix round's additive,\nnon-breaking response fields:\n\n- `recovered?: boolean` on the accounts.link() and accounts.solveCheckpoint()\n  201 responses — true only when the connect re\n[…]\ne new\nfields; adds pass-through + type-surface tests; CHANGELOG under 0.13.0.\nAccompanying request/response description improvements already merged into\nthe server ride along in the regenerated types.",
          "is_bot": false,
          "headline": "feat(accounts): regen types for connect-fix response fields",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-06T14:17:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "52a8451f2de2d7841dca9ae246cbce42f21fa8e1",
          "body": "Server-side fix (campaign feat/v2-migration-w1 @ 360747f2) makes the served\nOpenAPI express nullability on PATCH /v1/accounts/{id}'s proxy property and\nPATCH /v1/webhooks/{id}'s name property (both genuinely `.nullable()` at\nruntime). Regenerated by surgically adding `nullable: true` to exactly thos\n[…]\ng gen:types:fixture.\n\nAccountUpdateBody.proxy and the webhooks update body's name now carry `| null`\nin the generated type, matching the runtime schema. No version bump — 0.13.0\nunpublished amendment.",
          "is_bot": false,
          "headline": "chore(sdk): regen types — PATCH proxy now nullable",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-05T21:37:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bcde9d2a15a7dedaf0f4e0dbc78a6cf54f36bf6d",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.13.0",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-05T20:48:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8042c182caa14b190ec6666ca06869b1ad1de561",
          "body": "Checkpoint operations move account-in-path: solveCheckpoint(id, { code }),\nrequestCheckpoint(id), and pollCheckpoint(id) replace the old\nsubmit/resend/poll methods that carried account_id in the body. connect-link\nbecomes create-only; new createReconnectLink(id, body?) mints a hosted\nre-auth link. u\n[…]\n Types regenerated from\nthe current API surface.\n\nBREAKING CHANGE: submitCheckpoint, resendCheckpoint, and refresh are removed;\npollCheckpoint and update change signature; connect-link is create-only.",
          "is_bot": false,
          "headline": "feat(accounts): v2 accounts/auth surface reshape",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-05T20:48:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "051d00d6a48370918416c573a77f7ce0cd48c3f7",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.12.0",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-05T05:57:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f450a27fa83e3a87e6ac5c11ae16c9a91348b5ce",
          "body": "…king saveLead re-signature\n\nFixture-surgical regen of fixtures/openapi.json + src/generated/types.ts\n(the six new /v1/sales-navigator/{account-lists,lead-lists}... paths; the\nretired POST /v1/sales-navigator/leads/{user_id} removed, no alias).\n\nAdds accountLists/leadLists/browseAccountList/browseLe\n[…]\ne v2\nsave-lead surface: saveLead(userId, body) -> saveLead({ list_id, user_id,\naccount_id }) against POST /v1/sales-navigator/lead-lists/{list_id}/save\n(BREAKING, no alias — list_id is now mandatory).",
          "is_bot": false,
          "headline": "feat(sales-navigator): v2 list-surface cascade — 5 new methods + brea…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-05T01:26:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c77fcbb2959e583a9e303c5903e22f15cf15dbda",
          "body": "The server added this code for the companies.followers() non-admin mapping\nbut it was missing from the SDK's ErrorCode union and the transport's known-\ncode set, so it would have silently narrowed to INTERNAL on the wire.",
          "is_bot": false,
          "headline": "feat(errors): add RESOURCE_ACCESS_RESTRICTED error code",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-04T23:54:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fcdad8c8bc389f283bfd5874a64bbfd317f6ef2c",
          "body": "…les.getCompany\n\nNew companies namespace (get/employees/posts/jobs/followers) mirrors the\nserver's new Companies REST group. profiles.getCompany is removed (BREAKING) —\nits endpoint was hard-moved with no alias, so this is the intended compile-time\nsignal at call sites. Types regenerated from the campaign server's OpenAPI\ndocument, patched surgically into fixtures/openapi.json (verified: only the\n5 added + 1 removed companies paths differ, no sibling drift).",
          "is_bot": false,
          "headline": "feat(companies): add companies resource (5 methods) — hard-move profi…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-04T23:39:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9e47f2bb13b10d3d839166e1a9c43b2cf6d0d477",
          "body": "Wholesale type regen from the current OpenAPI surface plus the hosted\nconnect-session poll method, bringing the SDK current with the full\naccounts-overhaul surface:\n\n- accounts.getConnectSession(session_id) — poll a hosted connect session\n  minted by createConnectLink(); returns status + account_id \n[…]\ntatus on list, get, and both sides of state-diff\n  (previous_status/current_status now typed enums)\n- 501 response variant on accounts.update()\n\nPublic method surface 83 -> 84. Version already 0.11.0.",
          "is_bot": false,
          "headline": "feat(accounts): full accounts-overhaul regen + getConnectSession()",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-04T17:41:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f13d51172a686d9185e424c505f5a07f6cb64a64",
          "body": "New accounts.resendCheckpoint({ account_id }) re-sends the pending\nverification challenge notification for a connect in progress. Returns\n{ object, account_id, resent } — resent echoes the substrate outcome\nhonestly (false when the challenge type has nothing to re-send; never\nthrows just for that). \n[…]\ny.\n\nTypes generated from a surgical fixture patch (the one new path only,\ndiff-confirmed against the fixture — no sibling drift). Extends the\nAccounts surface to 11 methods (83 total). Bump to 0.11.0.",
          "is_bot": false,
          "headline": "feat(accounts): add accounts.resendCheckpoint() — checkpoint resend",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-04T13:55:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9b8b9306453f98a99f3205a5c2e09d28725495e1",
          "body": "…eve (#373)\n\nNew `jobs` namespace: jobs.get(jobIdOrUrl, query?) retrieves one public\nLinkedIn job posting's full detail, accepting either a bare numeric id or a\nfull job URL (the id is extracted client-side; the wire request always\ncarries the numeric id). Throws a client-side INVALID_REQUEST error\n\n[…]\nition), extending\nthe Recruiter surface to 18 methods.\n\nRegenerated types from a surgical fixture patch (the two new paths only,\ndiff-confirmed against the fixture — no sibling drift). Bump to 0.10.0.",
          "is_bot": false,
          "headline": "feat(jobs): add jobs.get() and recruiter.getJob() — job-posting retri…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-03T18:09:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e7dcf7b4e2c09df2b19c46670a0f26235e42881a",
          "body": "…ics (rides 0.9.0)\n\nRegenerated from the current API surface: quotas[] and\nrecommended_throttle_hint descriptions now state the advisory\ncontract (daily families never reject; only account.per_minute is a\nbinding limit enforced with HTTP 429). JSDoc-only, no shape change.",
          "is_bot": false,
          "headline": "docs(quotas): advisory usage-safety framing on quotas[] + hint semant…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-03T15:00:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "335156240ebce4c9f85a34fa4675e241ca56ae7c",
          "body": "…t (0.9.0) (#6)\n\nRegenerate types from the accounts endpoints only (scope-guarded diff\nconfirmed no other path drifted): username, premium_id, public_identifier,\nsubstrate_created_at, signatures, groups on both accounts.list() items and\naccounts.get(); seat_id added to accounts.get(). connected_at/last_checked_at\nnow consistently ISO-8601 UTC. All additive; no method signature changes.\n\nCo-authored-by: Raphael Redmer <ra.redmer@outlook.com>",
          "is_bot": false,
          "headline": "feat(accounts): account enrichment fields on list/get + seat_id on ge…",
          "author_name": "Raphael",
          "author_login": "rapha-red",
          "committed_at": "2026-07-03T12:09:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f4d102bc9c00502a61fa32c4c2b2bb92a5a1e1bb",
          "body": "…cumented",
          "is_bot": false,
          "headline": "release: 0.8.0 — recruiter job-lifecycle wired, search guard-rails do…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-02T16:22:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fccbdb80e54d37864e23b9a679cd7029d3ff9339",
          "body": null,
          "is_bot": false,
          "headline": "docs: flag annual_revenue enum narrowing as breaking for typed consumers",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-02T16:22:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "139051b634b14a525f9e55eba312c030bb36b99c",
          "body": "Recruiter job-lifecycle endpoints are fully implemented server-side\n(501 removed), richer parameter docs and surfaced defaults, and\nsearch filter guard-rail documentation (companies limit, jobs\nbenefits/commitments, people open_to, posts filter examples, SN\nrevenue buckets). No method signature changes.",
          "is_bot": false,
          "headline": "chore: bump version 0.7.0 -> 0.8.0",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-02T16:06:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e4413493767e6d7db35fdb07ae2d5ae3fe57b1d5",
          "body": "Recruiter job-lifecycle endpoints are now fully implemented server-side\n(501 stub responses removed), parameter documentation is richer across\nrecruiter/search surfaces, server-side defaults are now surfaced in\nJSDoc, and the Sales Navigator company revenue filter is now a bucketed\nenum. Search filt\n[…]\nn is also reflected: company\nsearch minimum page size, valid values for jobs benefits/commitments and\npeople open_to, and corrected post-search filter examples.\n\nNo resource method signatures changed.",
          "is_bot": false,
          "headline": "chore: regenerate types from live API surface",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-02T16:06:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b81cc10b5bbb645935010155c372987a3ac04280",
          "body": "BREAKING (typed consumers): recruiter.startChat 201 response drops\nattendee_ids and returns message_id (the opening message id), matching\nmessaging.startChat / salesNavigator.startChat. chat_id is now non-nullable\non a 201. Regenerated types from the updated recruiter chats path; request\nbody unchanged. Migration: read res.message_id.",
          "is_bot": false,
          "headline": "feat(sdk): align recruiter start-chat response to message_id (0.7.0)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-01T20:33:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aa074d202ee89113546a51da2adcf9ef017be5fe",
          "body": "…hes CHANGELOG + CLI dep)",
          "is_bot": false,
          "headline": "chore: bump version 0.5.0 -> 0.6.0 (SN/Recruiter parity release; matc…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-01T19:25:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1f947d94641725d484c01dfa0d4e0414a99ef363",
          "body": "…ter start-chat field rename + object discriminator\n\nBREAKING (typed consumers):\n- salesNavigator.syncMessages + recruiter.syncMessages: response sync_status -> status\n- recruiter.startChat request: attendee_ids -> attendees_ids (response attendee_ids unchanged)\n- recruiter.startChat response: gains object:\"chat_started\" discriminator, drops quota field",
          "is_bot": false,
          "headline": "feat(sdk): SN/Recruiter messaging parity — sync status rename, recrui…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-01T19:05:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "df837cd64c347a96f37e5d527f71158e6b10c017",
          "body": "… (0.5.0)\n\nRegenerate types from the current API surface:\n- people search: connections_of / followers_of are now string[] (arrays of\n  opaque member IDs) instead of a single string\n- posts search: nested posted_by / mentioning / author filter objects replace\n  the flat member_urn / company_urn field\n[…]\naries in the SDK JSDoc.\n\nBREAKING CHANGE: connections_of/followers_of (string -> string[]),\nlocation_within_area (string -> number), and the posts filter shape change\nare breaking for typed consumers.",
          "is_bot": false,
          "headline": "feat(search): v2 search request/response types + de-branded summaries…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-01T15:29:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1dd97515b0cb6f0b96c9ea8697a27e5ccf80d470",
          "body": "chore(release): @curviate/sdk 0.4.2 — reintegrate invites specifics.provider + 422 drop (regression fix)",
          "is_bot": false,
          "headline": "Merge pull request #5 from Curviate/chore/sdk-0.4.2-invites-reintegrate",
          "author_name": "Raphael",
          "author_login": "rapha-red",
          "committed_at": "2026-07-01T10:09:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "67fdea4c0c43f75f39afb78ed0833e221cbd5e54",
          "body": "…rovider + cancel/handle 422 drop\n\nReconciles two lines that diverged off 0.4.0: 0.4.1 (people-search id) and\nmain (6d41863 — invites specifics.provider + cancel/handle 422 drop). The 0.4.1\nrelease was cut off 0.4.0 and bypassed the invites types, dropping them from the\npublished/gitlinked SDK; this\n[…]\nfull superset: invites specifics.provider (sent+received), people-\nsearch id, and profile primary_locale + messaging status rename all present.\nVerified: check:types OK, check:clean OK, tsup build OK.",
          "is_bot": false,
          "headline": "chore(release): @curviate/sdk 0.4.2 — reintegrate invites specifics.p…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-07-01T10:05:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "15b6fa32066f9966b3cdd0c9e8cbdfb813ab7cee",
          "body": "Adds `id: string` (raw LinkedIn provider id, ACoAA… format) as the first\nproperty on the `people_search_result` item type. Regenerated from the\nupdated OpenAPI fixture (search-people id + limit-description trim on all\n4 search ops). No invites/messaging/recruiter/501 changes.\n\nBump 0.4.0 → 0.4.1 (additive patch).",
          "is_bot": false,
          "headline": "feat(types): people search item — add id field (0.4.1)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-06-30T19:21:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6d41863c99b4837ce973456fe27c81fffe0ece38",
          "body": "…vider + cancel/handle 422 drop (#3)\n\nAdds specifics.provider:\"LINKEDIN\" to InvitationSent/InvitationReceived item\nschemas, and removes the 422 response from the cancel and handle operations\n(both reflect the merged API surface). Regenerated on top of the current 0.4.0\ntypes via gen:types --fixture; diff is invites-only.\n\nCo-authored-by: Raphael Redmer <ra.redmer@outlook.com>",
          "is_bot": false,
          "headline": "chore(types): regenerate from staging OpenAPI — invites specifics.pro…",
          "author_name": "Raphael",
          "author_login": "rapha-red",
          "committed_at": "2026-06-30T18:15:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "71d5066021e163a75b4a5f806589f6283b539dc6",
          "body": "…d rename (0.4.0)\n\nRegenerated types from the merged API: adds primary_locale ({country,language}|null)\non Profile and OwnProfile; renames GET /v1/messages/sync response field sync_status to\nstatus (SN/Recruiter re-sync unchanged); neutral endpoint/error descriptions. Part of #335.",
          "is_bot": false,
          "headline": "feat: primary_locale on Profile/OwnProfile + account-sync status fiel…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-06-30T12:59:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fcb34295418647785100a47003b140333adc8a4c",
          "body": "Widen sendInMail surface union to sales_nav | recruiter | classic and\naccept a member URN or provider id for recipient_urn. Regenerated types\nfrom the current API reference (also refreshes stale endpoint\ndescriptions). Bumps to 0.3.0 (additive).",
          "is_bot": false,
          "headline": "feat(messaging): accept classic InMail surface (#328)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-06-29T19:11:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f9d765e0acd0cd631c85a4d08f876114365833ee",
          "body": "…n (0.2.1) (#2)\n\n* fix(sdk): stop injecting account_id on deleteMessage/addReaction (#324)\n\nBoth methods set accountIdIn:'none' — the server resolves the owning account\nserver-side from the message id, so the SDK must not inject account_id into\nquery or body. Adds AccountIdLocation:'none' branch to createContext. Bumps\nto 0.2.1 (patch); CHANGELOG updated.\n\n* chore(sdk): strip internal issue/spec refs for public repo (check-clean)\n\n---------\n\nCo-authored-by: Raphael Redmer <ra.redmer@outlook.com>",
          "is_bot": false,
          "headline": "fix(messaging): stop injecting account_id on deleteMessage/addReactio…",
          "author_name": "Raphael",
          "author_login": "rapha-red",
          "committed_at": "2026-06-29T11:41:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79eee0bfc96abaae27bff6aa170e5ae837026194",
          "body": null,
          "is_bot": false,
          "headline": "chore: normalize repository.url to git+https (npm canonical)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-06-28T17:50:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3ebbb5e498e7fb0df8bdca8297d83241825c20a5",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): bump @curviate/sdk to 0.2.0",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-06-28T17:15:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b93cff6f713ab684ed4b614924bb034fec01c91d",
          "body": "…lized OwnProfile, Chat subject (#1)\n\n* feat(transport): support array query params (repeated key serialization)\n\n* chore(types): regen from live server — is_premium/is_open_profile, linkedin_sections on getMe, Chat subject, OwnProfile enriched fields\n\n* feat(profiles): getMe accepts linkedin_sections; export ProfileGetMeParams; tests for is_premium/is_open_profile, enriched fields, Chat subject\n\n---------\n\nCo-authored-by: Raphael Redmer <ra.redmer@outlook.com>",
          "is_bot": false,
          "headline": "feat(profiles,chat): #319 SDK parity — getMe linkedin_sections, norma…",
          "author_name": "Raphael",
          "author_login": "rapha-red",
          "committed_at": "2026-06-28T17:13:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "63c47cfe8382502f632fc496a623af6a0d0092bf",
          "body": "The account-scoped context (`curviate.account(id)`) always injected\n`account_id` into the query string, regardless of the operation. That is\ncorrect for GET reads, body-less DELETEs, and filter-search POSTs (where\naccount_id is a documented query param), but wrong for account-scoped\nwrite requests t\n[…]\nnt.\n\nAdds a regression test asserting the wire location across namespaces:\nbody for JSON and multipart writes, query for reads, deletes, and search.\n\nBumps version to 0.1.1 and adds a CHANGELOG entry.",
          "is_bot": false,
          "headline": "fix: send account_id in the request body for account-scoped writes",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-06-22T18:10:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a446963ecfae9c36b918fca7b8321667a46bdd80",
          "body": "…i-leak guard",
          "is_bot": false,
          "headline": "chore: anonymize internal references across the public repo + add ant…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-06-22T07:58:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba621691c9b6c7589e5b7393bad2a2d305f8e1a7",
          "body": null,
          "is_bot": false,
          "headline": "fix: default baseUrl -> https://api.curviate.com (app host 404s on /v1)",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-06-22T07:52:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "31d050bb73d89f2ee895edee2498b67f2db778fb",
          "body": "…a fail)\n\nD1: account list items expose account_id, not id — fix every .id access on\naccount items (.account_id) and guard items? optional chain.\nD2: chat.last_message_text is not a real field — replace with chat.unread_count.\nD3: AccountListParams has no status param — remove { status: \"active\" } f\n[…]\n snippets into examples-check.ts, ran\ntsc --noEmit against strict tsconfig; confirmed zero errors. Deleted temp file.\npnpm test 150/150 green; grep -ri unipile exits clean; npm pack --dry-run 7 files.",
          "is_bot": false,
          "headline": "docs(sdk): fix README examples against real exported types (cycle-2 q…",
          "author_name": "Raphael Redmer",
          "author_login": "RaRedmer",
          "committed_at": "2026-06-21T20:03:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 12,
      "commits_last_year": 125,
      "latest_release_at": "2026-07-17T16:40:43Z",
      "latest_release_tag": "sdk-v0.17.0",
      "releases_from_tags": false,
      "days_since_last_push": 5,
      "active_weeks_last_year": 5,
      "days_since_latest_release": 6,
      "mean_days_between_releases": 2
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 50,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@curviate/sdk",
          "exists": true,
          "license": "MIT",
          "keywords": [],
          "ecosystem": "npm",
          "matches_repo": false,
          "registry_url": "https://www.npmjs.com/package/@curviate/sdk",
          "is_deprecated": false,
          "latest_version": "0.18.1",
          "repository_url": "https://github.com/curviate/sdk",
          "versions_count": 24,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 4056,
          "first_published_at": "2026-06-22T11:34:30.425000Z",
          "latest_published_at": "2026-07-18T10:07:28.907000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 5
        }
      ]
    },
    "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": [
        "fixtures/openapi.json"
      ],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 79415,
      "source_files_sampled": 63,
      "oversized_source_files": 1,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "zod",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.25.17"
        }
      ],
      "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": 11,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "RaRedmer",
          "commits": 115,
          "avatar_url": "https://avatars.githubusercontent.com/u/44050496?v=4"
        },
        {
          "type": "User",
          "login": "rapha-red",
          "commits": 10,
          "avatar_url": "https://avatars.githubusercontent.com/u/276905213?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.92
    },
    "quality_signals": {
      "has_ci": false,
      "has_tests": true,
      "ci_workflows": [],
      "has_docs_dir": false,
      "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": 0,
            "reason": "0 out of 3 merged PRs checked by a CI test -- score normalized to 0",
            "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/7 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": null,
            "reason": "no workflows found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": null,
            "reason": "no dependencies found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 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": null,
            "reason": "No tokens found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "5855d2d476aee0212348d33509248591f132edea",
        "ran_at": "2026-07-23T17:24:28Z",
        "aggregate_score": 2.5,
        "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": null,
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-18T09:57:29Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/Curviate/curviate-sdk",
    "host": "github.com",
    "name": "curviate-sdk",
    "owner": "Curviate"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 41,
      "inputs": {
        "security": 25,
        "vitality": 75,
        "community": 24,
        "governance": 39,
        "engineering": 34
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 75,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 58,
            "inputs": {
              "commits_last_year": 125,
              "human_commit_share": 1,
              "days_since_last_push": 5,
              "active_weeks_last_year": 5
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "5/52 weeks with commits",
                "points": 3.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "125 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 125
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 12,
              "latest_release_tag": "sdk-v0.17.0",
              "releases_from_tags": false,
              "days_since_latest_release": 6,
              "mean_days_between_releases": 2
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "12 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 12
                    }
                  }
                ],
                "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 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 2
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "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": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 39,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 14,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.92
            },
            "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 92% of commits",
                "points": 1.8,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 92
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": "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": 11,
              "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": "11/11 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 11,
                      "decided": 11
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/7 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": 35,
            "inputs": {
              "followers": 0,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "Curviate",
              "public_repos": 3,
              "account_age_days": 32
            },
            "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": "0 followers of Curviate",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "Curviate"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "3 public repos, account ~0 yr old",
                "points": 4.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 3
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "at_risk",
        "name": "Engineering Quality",
        "value": 34,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "critical",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 24,
            "inputs": {
              "has_ci": false,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": "0 out of 3 merged PRs checked by a CI test -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": 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": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "critical",
        "name": "Security",
        "value": 25,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Dangerous-Workflow, Packaging, Pinned-Dependencies, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "dangerous_workflow",
                    "packaging",
                    "pinned_dependencies",
                    "signed_releases",
                    "token_permissions"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 25,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 13,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 5,
              "scorecard_aggregate": 2.5
            },
            "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": "0 out of 3 merged PRs checked by a CI test -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/7 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no workflows found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "no dependencies found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file 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": "No tokens found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "at_risk",
        "name": "AI Readiness",
        "value": 48,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Pinned-Dependencies. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_pinned_dependencies"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 37,
            "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,
              "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": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "no dependencies found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 99,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 79415,
              "source_files_sampled": 63,
              "oversized_source_files": 1
            },
            "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": "1/63 source files over 60KB",
                "points": 54.1,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 63,
                      "oversized": 1
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [],
              "has_mcp_signal": false,
              "api_schema_files": [
                "fixtures/openapi.json"
              ]
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": "fixtures/openapi.json",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "fixtures/openapi.json"
                    }
                  }
                ],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "npm package '@curviate/sdk' points at a different repository (https://github.com/curviate/sdk); excluded from ecosystem scoring",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index npm:@curviate/sdk@0.18.1; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-23T17:24:41.275574Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/c/Curviate/curviate-sdk.svg",
  "full_name": "Curviate/curviate-sdk",
  "license_state": "standard",
  "license_spdx": "MIT"
}

评分是信号,而非担保。 评分反映的是 GitHub 上公开可见的实践——不是代码审计,也不是安全保证。

缺失数据将被剔除并重新归一化权重,绝不按零分计。方法论已版本化并公开:指标 v1.13.0、模式 v0.27.0—— 完整方法论 · 指标知识库.

单项结果在整体记录中的位置: 汇总统计npm.