公开记录
软件健康报告模式 0.23.0 · 指标 1.13.0 · 2026-07-21 21:26 UTC

duyet / agentstate

TypeScriptMIT★ 2 星标⑂ 1 复刻始于 2026年3月在 GitHub 上查看 ↗

duyet/agentstate 的健康指数为 100 分中的 66 分,处于「中等」区间。 其得分最高的类别是Engineering Quality(82/100),最低的是Community & Adoption(41/100)。 最近一次更新在 4 天前。 近期的大部分工作由 1 位贡献者完成。

66
总分 / 100
中等

软件健康指数

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

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

评分画像

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

所有权

duyet个人账户
814 关注者544 个公开仓库始于 2013年7月

该仓库由个人账户拥有。相较于组织支持的项目,单一所有者项目的延续性风险更高。

软件包生态系统

注册表软件包版本月下载量版本数最近发布标签
npm@agentstate/sdk0.1.48,05254 天前ai-agentsagent-memoryconversation-historylanggraphvercel-ai-sdkmcpagent-statecloudflare-workers
PyPIagentstate指向其他仓库——不计分1.0.2-3333 天前aiagentsstatemanagementfirebasepersistentstoragereal-time

按类别列示的指标

活力

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

79良好 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 4 天前
8.3/36提交节奏 — 52 周中有 12 周有提交
18/18提交量 — 最近一年 452 次提交
10/10OpenSSF Scorecard:Maintained — 30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
所用输入
commits_last_year452
human_commit_share0.92
days_since_last_push4
active_weeks_last_year12

发布纪律

90优秀
评分方式
27/27有发布版本 — 已发布 4 个发布版本
36/36发布时效 — 最近一次发布版本于 30 天前
27/27发布节奏 — 约每 2.3 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — Project has not signed or included provenance with any releases.
所用输入
releases_count4
latest_release_tagv0.1.4
releases_from_tags
days_since_latest_release30
mean_days_between_releases2.3

社区与采用

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

41存在风险 · 占总体的 18%
评分方式
0/60星标 — 2 个星标
0/25复刻 — 1 个复刻
0/15关注者 — 0 位关注者
所用输入
forks1
stars2
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonbelow_threshold

社区健康

70良好
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(MIT)
18/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
评分方式
52.1/80月度下载量 — npm 合计每月 8,052 次下载
0/20注册表被依赖数 — 该生态系统不报告此项
所用输入
packages@agentstate/sdk
dependents
ecosystemsnpm
total_downloads
monthly_downloads8,052
已排除计分(无数据或不适用):注册表被依赖数。 其余权重已重新归一化。

可持续性与治理

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

65中等 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
9/22.5提交分布 — 头号贡献者编写了 60% 的提交
4.1/13.5贡献者广度 — 3 位贡献者
10/10OpenSSF Scorecard:Contributors — project has 5 contributing companies or organizations
所用输入
bus_factor1
contributors_sampled3
top_contributor_share0.6
评分方式
36.3/46.8议题解决 — 78% 的议题已关闭
35.8/38.3PR 接受 — 已裁定的 PR 中 259/277 已合并
0/15OpenSSF Scorecard:Code-Review — Found 2/27 approved changesets -- score normalized to 0
所用输入
merged_prs259
open_issues25
closed_issues87
issue_closed_ratio0.777
closed_unmerged_prs18
评分方式
10/30所有权背书 — 个人(用户)账户
0/20已验证域名 — 不适用于个人账户
20.9/25所有者影响力 — duyet 有 814 位关注者
25/25既往记录 — 544 个公开仓库,账户约 13 年
所用输入
followers814
owner_typeUser
is_verified
owner_loginduyet
public_repos544
account_age_days4,754
已排除计分(无数据或不适用):已验证域名。 其余权重已重新归一化。
评分方式
25/25已发布且可解析 — npm 上有 1 个软件包
35/35发布时效 — 最近一次发布于 4 天前
20/20版本历史 — 5 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packages@agentstate/sdk
ecosystemsnpm
any_deprecated
min_days_since_publish4

工程质量

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

82良好 · 占总体的 20%

工程实践

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

文档

80良好
评分方式
30/30README
25/25文档目录
15/15文档 / 主页站点 — https://agentstate.app
0/10仓库描述
0/10主题标签
10/10Wiki
所用输入
topics
has_wiki
homepagehttps://agentstate.app
has_readme
has_docs_dir
has_description

安全

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

58中等 · 占总体的 16%

安全态势

48存在风险
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.5/2.5CI-Tests — 28 out of 28 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 2/27 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 5 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
7.5/7.5Maintained — 30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
5/5Security-Policy — security policy file detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 28 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated18
scorecard_versionv5.5.0
checks_inconclusive0
scorecard_aggregate4.8
评分方式
35/35直接依赖不含已知公告 — 没有直接依赖携带已知公告
25/25间接依赖不含已知公告 — 没有间接依赖携带已知公告
0/40没有长期未处理的公告 — 没有公告带有发布日期
所用输入
sourceosv
advisories0
affected_packages0
assessed_packages5
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
已排除计分(无数据或不适用):没有长期未处理的公告。 其余权重已重新归一化。 比对的是 pypi:agentstate@1.0.2 的运行时依赖闭包——安装已发布的软件包时真正被拉取进来的内容——共 5 个软件包。 未对可达性进行分析。

AI 就绪度

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

76良好 · 占总体的 0%
评分方式
45/45代理指令 — AGENTS.md, CLAUDE.md, packages/api/src/content/agents.md, packages/dashboard/public/agents.md
15/15机器可读文档(llms.txt) — 存在 llms.txt
40/40可读的提交历史 — 92 次人类提交中有 91 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.989
agent_instruction_filesAGENTS.md, CLAUDE.md, packages/api/src/content/agents.md, packages/dashboard/public/agents.md
agent_instruction_max_bytes19,307
评分方式
0/18一条命令的引导启动
22/22自动化测试
11/11Lint / 格式化配置 — biome.json
11/11静态类型检查 — examples/fleet-leases/tsconfig.json, packages/api/tsconfig.json, packages/dashboard/tsconfig.json, packages/mcp/tsconfig.json, packages/sdk/tsconfig.json, packages/shared/tsconfig.json, tsconfig.json
0/10可复现环境
2/10已体现的代理实践 — 最近 100 次提交中有 1 次由代理编写或署名代理
8/8自动化维护 — 最近 100 次提交中有 7 次为自动依赖更新
0/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
所用输入
has_nix
has_tests
lockfiles
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configsexamples/fleet-leases/tsconfig.json, packages/api/tsconfig.json, packages/dashboard/tsconfig.json, packages/mcp/tsconfig.json, packages/sdk/tsconfig.json, packages/shared/tsconfig.json, tsconfig.json
agent_commit_share0.01
toolchain_manifests
dependency_bot_commit_share0.07
评分方式
45/45可类型检查的代码 — TypeScript(静态类型)
54.8/55可控的文件大小 — 采样的 321 个源文件中有 1 个超过 60KB
所用输入
primary_languageTypeScript
largest_source_bytes65,759
source_files_sampled321
oversized_source_files1
评分方式
0/40API 模式(OpenAPI/GraphQL/proto)
20/20MCP 服务器
40/40可运行示例 — examples, recipes
所用输入
example_dirsexamples, recipes
has_mcp_signal
api_schema_files

关键数据

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

数据采集警告

  • Could not fetch npm package '@agentstate/mcp' from its registry
  • pypi package 'agentstate' points at a different repository (https://github.com/ayushmi/agentstate); excluded from ecosystem scoring

更多细节

Star 与 Fork 历史 2 ★ / 1 ⇿
2Star
1Fork
2发布

每颗 star 和每个 fork 的添加时间,来自 GitHub 并按天汇总。累计增长位于其构成来源——每日新增——的正上方,二者可相互对照:稳定的自然增长与短暂的突增形态截然不同。当这一差别可被衡量时,它会作为增长真实性予以报告。

0011222112026-032026-052026-06
主版本 0次版本 0修订 2
OpenSSF Scorecard 4.8 / 10
4.8综合

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

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests28 out of 28 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 2/27 approved changesets -- score normalized to 0
10Contributorsproject has 5 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
10Security-Policysecurity policy file detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities28 existing vulnerabilities detected
直接依赖 27
注册表软件包版本约束清单文件
npm@clerk/backend^3.7.0packages/api/package.json
npmdrizzle-orm^0.45.2packages/api/package.json
npmhono^4.12.21packages/api/package.json
npmnanoid^5.1.0packages/api/package.json
npmzod^3.24.0packages/api/package.json
npmzod-to-json-schema^3.25.2packages/api/package.json
npm@agentstate/sharedworkspace:*packages/dashboard/package.json
npm@clerk/react^6.6.6packages/dashboard/package.json
npm@fontsource-variable/hanken-grotesk^5.2.8packages/dashboard/package.json
npm@fontsource-variable/jetbrains-mono^5.2.6packages/dashboard/package.json
npm@fontsource-variable/space-grotesk^5.2.8packages/dashboard/package.json
npm@phosphor-icons/react^2.1.10packages/dashboard/package.json
npmclsx^2.1.1packages/dashboard/package.json
npmecharts^6.1.0packages/dashboard/package.json
npmmotion^12.38.0packages/dashboard/package.json
npmnext-themes^0.4.6packages/dashboard/package.json
npmreact19.2.7packages/dashboard/package.json
npmreact-dom19.2.7packages/dashboard/package.json
npmreact-markdown^10.1.0packages/dashboard/package.json
npmremark-gfm^4.0.1packages/dashboard/package.json
npmsonner^2.0.7packages/dashboard/package.json
npmtailwind-merge^3.5.0packages/dashboard/package.json
npmtw-animate-css^1.4.0packages/dashboard/package.json
npmzod^4.4.3packages/dashboard/package.json
npm@modelcontextprotocol/sdk^1.29.0packages/mcp/package.json
npmzod^3.25packages/mcp/package.json
PyPIhttpx>=0.28.1packages/python-sdk/pyproject.toml
全部依赖 57

来自 GitHub 依赖图的完整解析依赖集合:26 个直接依赖与 31 个间接(传递)软件包。仓库提交锁文件时,传递闭包才是完整的。

注册表软件包版本关系
npm@clerk/backend^3.7.0直接
npm@clerk/react^6.6.6直接
npm@fontsource-variable/hanken-grotesk^5.2.8直接
npm@fontsource-variable/jetbrains-mono^5.2.6直接
npm@fontsource-variable/space-grotesk^5.2.8直接
npm@modelcontextprotocol/sdk^1.29.0直接
npm@phosphor-icons/react^2.1.10直接
npmclsx^2.1.1直接
npmdrizzle-orm^0.45.2直接
npmecharts^6.1.0直接
npmhono^4.12.21直接
npmmotion^12.38.0直接
npmnanoid^5.1.0直接
npmnext-themes^0.4.6直接
npmreact19.2.7直接
npmreact-dom19.2.7直接
npmreact-markdown^10.1.0直接
npmremark-gfm^4.0.1直接
npmsonner^2.0.7直接
npmtailwind-merge^3.5.0直接
npmtw-animate-css^1.4.0直接
npmzod^3.24.0直接
npmzod^3.25直接
npmzod^4.4.3直接
npmzod-to-json-schema^3.25.2直接
PyPIhttpx直接
npm@astrojs/check^0.9.9间接
npm@astrojs/react^6.0.0间接
npm@cloudflare/vitest-pool-workers^0.18.0间接
npm@cloudflare/workers-types^5.0.0间接
npm@langchain/core^1.1.49间接
npm@langchain/langgraph-checkpoint^1.1.1间接
npm@resvg/resvg-js^2.6.2间接
npm@rollup/rollup-linux-x64-gnu^4.60.0间接
npm@tailwindcss/vite^4.3.0间接
npm@types/node^26.0.0间接
npm@types/react^19间接
npm@types/react-dom^19间接
npmastro^7.0.0间接
npmdrizzle-kit^0.31.10间接
npmesbuild0.28.1间接
npmshadcn^4.10.0间接
npmtailwindcss^4间接
npmtsup^8.5.1间接
npmtypescript^5间接
npmtypescript^5.7.0间接
npmtypescript^5.9.3间接
npmtypescript^6.0.3间接
npmvitest^4.1.6间接
npmvitest^4.1.9间接
npmwrangler^4.93.0间接
PyPIlanggraph间接
PyPIlanggraph-checkpoint间接
PyPIpytest间接
PyPIpytest-asyncio间接
PyPIrespx间接
PyPIsetuptools间接
依赖安全公告 0

安装 pypi:agentstate@1.0.2 会引入 5 个包(直接与传递):其中 0 个存在已知公告,0 个为直接依赖。

没有已知公告影响已评估的依赖。

公告表示依赖图中记录的版本落入某条公告的受影响范围。可达性未经分析,且依赖图包含开发与测试的版本固定——某项发现可能只涉及工具链而非交付的软件。

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 2877,
      "has_wiki": true,
      "homepage": "https://agentstate.app",
      "languages": {
        "CSS": 13378,
        "Astro": 92569,
        "Shell": 3822,
        "Python": 91557,
        "JavaScript": 34735,
        "TypeScript": 1428819
      },
      "pushed_at": "2026-07-17T16:17:36Z",
      "created_at": "2026-03-15T13:07:17Z",
      "owner_type": "User",
      "updated_at": "2026-07-17T16:17:47Z",
      "description": null,
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript"
      ]
    },
    "owner": {
      "blog": "https://duyet.net",
      "name": "duyet",
      "type": "User",
      "login": "duyet",
      "company": null,
      "location": "Earth",
      "followers": 814,
      "avatar_url": "https://avatars.githubusercontent.com/u/5009534?v=4",
      "created_at": "2013-07-15T01:54:31Z",
      "is_verified": null,
      "public_repos": 544,
      "account_age_days": 4754
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.1.4",
          "kind": "patch",
          "published_at": "2026-06-21T04:16:59Z"
        },
        {
          "tag": "v0.1.3",
          "kind": "patch",
          "published_at": "2026-06-17T07:25:29Z"
        },
        {
          "tag": "v0.1.2",
          "kind": "patch",
          "published_at": "2026-06-14T06:17:32Z"
        },
        {
          "tag": "v0.1.1",
          "kind": "patch",
          "published_at": "2026-06-14T06:08:09Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "9a12ed2e8c11f61bc1e42471c4b1c60b5182cb34",
          "body": "… org (#391)\n\n* fix(dashboard): render code-tabs lines as blocks + auto-activate sole org\n\nTwo landing/dashboard fixes:\n\n- code-tabs: each highlighted code line was an inline <span> with no newline\n  between siblings, so inside <pre> the whole snippet collapsed onto one\n  horizontal row. Render each\n[…]\n setActive that clears the guard and skips the reload on failure.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(dashboard): render code-tabs lines as blocks + auto-activate sole…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T16:17:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5ff291a5fed3a3e90c213d0f7cae74f2bc783148",
          "body": "* feat(dashboard): show and switch the active org in the sidebar\n\nThe sidebar had no active-org indicator and no switcher — the only org\nsurface was a settings link. But the org id is load-bearing for every\nproject-scoped read, so a mismatch presented as an empty account with no\nway to see or correc\n[…]\neaving the mobile label unassociated. Derive the id with useId().\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix: make the active org visible and org orphaning observable (#390)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T13:17:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "935527c8a48d2dea696d9404a10d0af70dc391f3",
          "body": "…nt (#386)\n\nAdd .omo/ and .commandcode/ (local Ralph loop / Command Code scratch\nstate) to .gitignore, and let biome reflow a long import line in\ncreate-org-content.tsx.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "chore: gitignore local agent-tool state dirs, format create-org-conte…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T07:53:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "817467e461fd36fdb591972cbdaeb2b76fb3e477",
          "body": "Plan 006. The Idempotency-Key flow on state PUT/DELETE was read-then-\nmutate-then-store: two concurrent requests with the same key could both\nmiss the initial read, both run the mutation (each appending a\nstate_events row), and then silently lose the second idempotency record\nto INSERT OR IGNORE. Id\n[…]\n isn't stuck behind a dead claim.\n\nRoute handlers wrap the mutation in try/finally so any failure path\n(service error or thrown exception) releases the claim.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): claim idempotency keys before state mutations (#385)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T07:51:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7bb864036af0bd4eccad4638c289f675c15e380c",
          "body": "validation.ts and webhook.ts each declared their own copy of the\nsupported webhook event list; adding a new event to only one would\nsilently split validation from delivery. webhook.ts now imports\nWEBHOOK_EVENT_TYPES from validation.ts instead of redeclaring it.\n\nFixes #378\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): dedupe supported webhook event types into one constant (#384)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T06:35:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bc0b32a4da14ca5bb1dec0bad4baad98f2e7f678",
          "body": "…ations, error states (#379)\n\n* fix(dashboard): trap and restore focus in Dialog component\n\nAdds WAI-ARIA modal focus management to the shared Dialog primitive:\nfocus moves into the panel on open, Tab/Shift+Tab cycles within it,\nand focus is restored to the triggering element on close. Fixes the\ngap\n[…]\nc.).\n\nCloses #298\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n* merge main into claude/w12-dashboard-a11y-ux\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(dashboard): a11y and UX fixes — focus trap, keyboard nav, confirm…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T06:31:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "331738794113f1b6ce6cf2b92ad238eb7afbf979",
          "body": "…d dashboard CSP (#383)\n\n* fix(api): pad scope-denied timing and share AUTH_CACHE in scopedAuth\n\nAuth failures were already padded to a 300ms floor so invalid\ncredentials are indistinguishable by timing, but scopedAuth's\nscope-denied 403 branches returned immediately, letting a caller\nconfirm creden\n[…]\nhould do a final live-browser check before flipping to\nenforcing.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): pad scope-denied timing, share AUTH_CACHE in scopedAuth, ad…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T06:30:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1ea590745f001480c296957d19846e0fa0d7fec3",
          "body": "* fix(api): correct listTraces pagination to prevent false has_more and dropped rows\n\nlistTraces fetched exactly `limit` rows and set has_more = rows.length ===\nlimit, so an exactly-full final page reported a bogus next page. It also\ncursored on a bare updated_at with no tie-break, so traces sharing\n[…]\nm:write keeps working for create + verify\nunchanged.\n\nCloses #348\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): traces pagination, trace scoping, and claim:read scope (#381)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T06:16:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fd306ea899ddf4460a3b5c7d4927f5246e82dd80",
          "body": "PR #356 restored the comparison page (compare.astro) but the sitemap\ndrift check added in #358 fails CI because /compare is missing from\nsitemap.xml. Add the entry so main + dependents go green.\n\nCo-authored-by: CommandCodeBot <noreply@commandcode.ai>",
          "is_bot": false,
          "headline": "fix(dashboard): add /compare to sitemap.xml",
          "author_name": "Duyet Le",
          "author_login": "duyet",
          "committed_at": "2026-07-17T04:25:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d3a329e2eeb141f90c77a2f85afeecb2a0c94118",
          "body": "Plan 007. renewLease/releaseLease did check-then-act: SELECT the lease,\nbranch in JS, then UPDATE with no state guard in the WHERE. A concurrent\nrelease or expiry-driven re-acquire between the select and the update\ncould let renewLease stamp a fresh future expires_at onto an\nalready-released lease, \n[…]\ns so client-visible\nsemantics are unchanged. Mutual exclusion on acquire was already safe\nvia the partial unique index; this is a correctness-of-response fix.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): guard lease renew/release updates with state predicates (#382)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T03:41:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3a582a3df60dd7aeecbd1f6d16659eb790cfc43a",
          "body": "…-safe signatures (#380)\n\n* fix(api): exact-match webhook event subscriptions via json_each\n\ngetActiveWebhooksForEvent matched events with a substring LIKE over the\nJSON-serialized array, so overlapping event names (e.g. \"state.update\"\nvs \"state.updated\") would cross-match. Use json_each membership \n[…]\n\nreference implementation, and retry/dedup behavior.\n\nCloses #344\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): webhook exact-match, parallel delivery, retry tests, replay…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T03:41:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2cf90e0de162772be54f96062c57dfe1db479380",
          "body": "* docs: fix conversations/messages API reference to match live code\n\nThe \"current\" /api/v1 sections described a fictional \"V2\" convention set\n(PATCH update, ?include=messages opt-in, 204 append response, created_at\ncursor) that was drafted but never actually shipped. The real shared\nhandler (used by\n[…]\ny so this\ndoesn't recur.\n\nFollow-up to #333 per team-lead review.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs: fix API reference and project docs to match live code (#377)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T03:41:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a6a0650a666c8ed6b40a0e5de3b5abd840793447",
          "body": "…376)\n\n* fix(api): stop reflecting localhost origins and wildcard-with-credentials in CORS\n\nALLOWED_ORIGINS hardcoded localhost/127.0.0.1 entries that were also served in\nproduction (single Worker, no per-env origin list), letting any page open on\nthose loopback ports make credentialed cross-origin \n[…]\ns column null or absent) keep full access unchanged.\n\nCloses #346\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): CORS credential leak + empty-scopes privilege escalation (#…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T03:40:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "370f2ac024fb82808d2bb4010bf9d8b8d94790db",
          "body": "* docs(plans): track the plans directory and add a status index\n\nThe 10 implementation plans were untracked, so they existed only on one\nmachine while every PR referenced them by path, and no worktree could see\nthem. Each plan also instructs its executor to \"update this plan's row in\nplans/README.md\n[…]\nleteConversation\nand will conflict, plus a suggested merge order.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(plans): track the plans directory and add a status index (#371)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T03:40:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "943f2d8860483f435e65e6108099f314cfb9c557",
          "body": "…370)\n\nThe dashboard analytics endpoint (GET /v1/projects/:id/analytics)\ncaches results in AUTH_CACHE for 60-300s under\nanalytics:public:{projectId}:{range}, but createConversation and\ndeleteConversation never busted it. Deleting conversations showed\nstale, too-high counts for up to 5 minutes.\n\nExpl\n[…]\n of time, so bust all three cached\nranges (7d/30d/90d) for the project via a new\nlib/analytics-cache.ts helper, fire-and-forget via executionCtx.\n\nCloses #352\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): invalidate analytics cache on conversation create/delete (#…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T03:40:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "93c28791f3d544dfd5512d754d83a98703895b41",
          "body": "…#359)\n\nZero tests existed for GET /v1/conversations/search despite it being a\nsecurity-relevant query path (LIKE-wildcard escaping) with composite-cursor\npagination. Characterizes: happy-path snippet matching, literal '%'/'_'\nescaping (excluding non-literal variants), the intentionally-unescaped '['\ncase, q validation, malformed/legacy cursor handling, and a two-page cursor\nwalk asserting no overlap/gaps.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "test(api): cover conversation search escaping and cursor pagination (…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T03:40:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2657e5d978faec1f21d8d5b47e6f0a7f99f316d4",
          "body": "…, README badges (#358)\n\n* feat(seo): add robots.txt with sitemap pointer\n\nThe Workers asset binding's SPA fallback silently served index.html for\n/robots.txt since the file never existed, giving crawlers no crawl\ndirectives and hiding the sitemap location.\n\nCloses #307\n\nCo-Authored-By: Duyet Le <me\n[…]\ndges alongside the existing\nLicense/PRs-welcome row.\n\nCloses #313\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(seo): robots.txt, noindex, JSON-LD, sitemap drift check, keywords…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T03:40:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f25b2dcd3d34bfa6a8c41e7b2f81d1f81792fa44",
          "body": "* fix(api): rate-limit the states router\n\nEvery write-heavy states route (watch, query, lease, events, PUT, GET,\nDELETE) attached scopedAuth per-route but never chained\nrateLimitMiddleware, so an authenticated key could drive unlimited D1\nwrites and Durable Object notify traffic. Add the limiter aft\n[…]\nstates PUT still\nsucceeds under the limit.\n\nRefs #340, #349, #350\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): rate-limit states/leases/claims/mcp coordination routes (#357)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T03:40:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f5f811fc12e7acccd3b92620a726ef2cea9e6391",
          "body": "…ce (#356)\n\n* feat(dashboard): restore primitives grid, comparison table, API surface\n\nPR #339 (shadcn redesign) dropped three content blocks from the landing\npage that existed nowhere else: the five-primitives grid, the\nmemory-vs-AgentState comparison table, and the API-surface endpoint\ntable. Reco\n[…]\nit to API_BASE_URL to match every other\noccurrence in docs.astro.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): restore primitives grid, comparison table, API surfa…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T03:40:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5e6abe422d0ea634cdfd0a3b4ab85e2531ec7f76",
          "body": "Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): update dependency picomatch to v4 (#282)",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-07-17T02:05:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aaf05ac2df312b586602b7b3b1215df280013d3c",
          "body": "…(#355)\n\n* fix(states): atomically gate writes on leases and idempotency keys\n\nCloses two TOCTOU races in the state mutation path:\n\n- Leases (#289): the lease check was a separate SELECT before the write\n  batch, so a lease that expired or was handed off between check and write\n  still let the stale\n[…]\nlready fixed in code for #327) is corrected\nto match.\n\nFixes #325\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix: batch of triaged correctness bugs and small dashboard/SDK fixes …",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-17T01:28:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ce9a1fac824e599ae83be5ea3cc3fdc42a0c2f5d",
          "body": "…, chat components (#339)\n\n* feat(dashboard): add shadcn semantic token aliases to design system\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n* feat(dashboard): rebuild landing page with shadcn-style blocks\n\nSplit hero with code demo, numbered workflow, feature \n[…]\n\nconsistent px-6/gap-6 shells and bg-card/border-border surfaces.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): shadcn/ui redesign — landing page, dashboard spacing…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-16T19:27:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "42b30dc443e36a1377f2cd82681b99199f50ffb2",
          "body": "…olish\n\n- Add dedicated /dashboard/keys page with secure one-time key copy (sessionStorage, never echoed in table)\n- Add \"API Keys\" sidebar nav item and link it from the landing-page feature card\n- Replace static agent.ts hero snippet with a tabbed CodeTabs demo for TypeScript, Vercel AI, LangGraph,\n[…]\nsive features showcase (all 23 features)\n- UI polish: theme-toggle cross-fade, concentric radii, press feedback + 40px hit areas on raw buttons\n\nCo-Authored-By: CommandCodeBot <noreply@commandcode.ai>",
          "is_bot": false,
          "headline": "feat(dashboard): add API Keys page, tabbed hero demo, and interface p…",
          "author_name": "Duyet Le",
          "author_login": "duyet",
          "committed_at": "2026-07-15T05:49:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "46025acc80dceeb512034fd2a5b6157d2d187601",
          "body": "* chore(deps): update dependency @cloudflare/workers-types to v5\n\n* fix(api): type ExecutionContext generically for workers-types v5\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>\nCo-authored-by: duyetbot <bot@duyet.net>\nCo-authored-by: Duyet Le <me@duyet.net>",
          "is_bot": true,
          "headline": "chore(deps): update dependency @cloudflare/workers-types to v5 (#280)",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-07-10T00:12:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dcea99958118ca2b696a0f1556b57437cd5d3e2f",
          "body": "…(#281)\n\n* feat: enable Cloudflare Workers Cache for public read-only endpoints\n\nEnable Workers Cache (\"cache\": { enabled: true }) on the API Worker and set\nCache-Control: public on the genuinely public, unauthenticated, static GETs\nonly: /api (health, max-age=60/swr=300) and /llms.txt, /agents.md,\n\n[…]\nject — no re-parse cost on cache misses/bypasses or in local dev.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat: enable Cloudflare Workers Cache for public read-only endpoints …",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-07T00:23:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4c09ba28d59d56888ccba9f2c60dcf21e0557efd",
          "body": "…18.0 (#279)\n\nCo-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): update dependency @cloudflare/vitest-pool-workers to ^0.…",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-07-07T00:23:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4ed75ef48da7cb87e6de1cc52f0c9e591f6f342c",
          "body": "…shboard (#276)\n\n* fix(auth): isolate org-less users per-account instead of a shared default\n\nDerive a per-user org discriminator (personal:${clerkUserId}) when a Clerk\nsession has no active organization, and drop the \"default\" fallbacks in\nclerk-session.ts and routes/projects.ts. Previously every o\n[…]\no the panel doesn't show the previous conversation while loading.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix: address codebase-analysis findings across API, SDKs, MCP, and da…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-03T00:14:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ac52fb50b6845a3e03619d5358b7d151033db83f",
          "body": "…252)\n\n* refactor(dashboard): redesign traces page to design-system v2\n\nReplace traces-page.tsx's inline duplicate PageHeader with the shared\ncomponents/dashboard/page-header. Swap the hand-rolled <table> waterfall\nlist for the canonical Table/TableHeader/TableRow/TableHead/TableCell/\nTableSkeleton \n[…]\nmestamps (0 is valid)\n\nApplies CodeRabbit suggestions on PR #252.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "refactor(dashboard): redesign traces page to design-system v2 (D4) (#…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T06:40:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "909566680e37c6e3bf751dd4e564fb23cc2f8eb9",
          "body": "* refactor(dashboard): redesign domains page to v2 design system\n\nReplace the inline header with the shared PageHeader, flatten the\nover-nested domain-card sub-components (fold actions + status badge\ninto the card, drop the redundant _components.tsx re-export), swap\nthe hand-rolled domain input for \n[…]\nor showAddForm toggle\n\nApplies CodeRabbit suggestions on PR #248.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "style(dashboard): redesign Domains page to design-system v2 (D6) (#248)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T06:38:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "48986c6ef947b0e8ecd55d8a0448d2f454655cfe",
          "body": "…tem v2 (D7) (#247)\n\n* feat(dashboard): redesign organizations settings to design-system v2\n\nConvert list/create/members pages under settings/organizations to the\ncanonical vermilion-accent design system: shared PageHeader on all three\nroutes, Input/Select primitives replace raw <input>/<select>, Ta\n[…]\nIndex/preventDefault)\n\nApplies CodeRabbit suggestions on PR #247.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "style(dashboard): redesign organizations/settings pages to design-sys…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T06:38:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c62c181bd2698e93d146d4b8343fc610db46a49a",
          "body": "…(D1) (#250)\n\n* feat(dashboard): bold premium redesign of marketing home page\n\nRework the landing page hero, primitives section, and CTA to match\nVercel/Linear/Resend-tier polish while staying strictly within the\ndesign-system-v2 token vocabulary (vermilion accent, canonical color/\nspacing/radius to\n[…]\nnditional\ninner shapes. Applies CodeRabbit suggestion on PR #250.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): bold redesign of marketing home to design-system v2 …",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T06:37:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "309d96536cf1c50d49a4aebe50887e492b978738",
          "body": "…2) (#249)\n\n* style(dashboard): align docs/brand/oauth pages to design-system v2 tokens\n\nReplace hardcoded blue accent (#3b82f6 -> vermilion #e2664d) on the brand\nsheet, fix stale \"accent blue\" copy, and align the radius showcase with\nthe true --radius-sm/--radius/--radius-lg/--radius-xl scale.\n\nMig\n[…]\nfore\ncalling closest(). Applies CodeRabbit suggestion on PR #249.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "style(dashboard): align docs/brand/oauth pages to design-system v2 (D…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T06:37:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "205136e6001a34c7e7602ee85188b30f37c4fbff",
          "body": "…(D8) (#246)\n\n* style(dashboard): convert Integrate page to canonical design tokens\n\nReplace the shared brand `Pill`/`CodeBlock` imports (still on legacy\nshadcn-alias tokens like border-border/bg-card/text-muted-foreground)\nwith the canonical `Badge` primitive and a page-local `CodeBlock` that\nuses \n[…]\ne-after-unmount. Applies\nCodeRabbit review suggestion on PR #246.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "style(dashboard): redesign Integrate page to canonical design tokens …",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T06:36:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c46186c1e716543be295e903da50b3b08c0da055",
          "body": "…253)\n\nMigrate the Projects listing and project-detail pages to the v2 design\nsystem: adopt the shared PageHeader, use canonical spacing utilities\n(page-padding, space-y-section, gap-component, card-padding, etc.)\ninstead of ad-hoc padding/gaps, remove redundant heading weight\noverrides now handled \n[…]\ndead _dashboard-header\nafter switching to the shared PageHeader. No functional changes —\ncreate project, key management, tabs, and empty states all preserved.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): redesign projects listing and project detail (D3) (#…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T06:33:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "35b9fcf7548b79633e8cfe27d42909ecbc4e5500",
          "body": "style(dashboard): redesign Analytics page to design-system v2 (D5)",
          "is_bot": false,
          "headline": "Merge pull request #251 from duyet/redesign/d5-analytics",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T06:22:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3e0669a45e96ac3f5af93169a377db721bc56982",
          "body": "Replace hardcoded chart colors (#3b82f6, #34d399, #f59e0b, #f87171) and\necharts chrome colors (tooltip, axis, gridlines) with the chart-1..5\ndesign tokens, resolved at runtime via getComputedStyle so series and\nchrome colors track the active light/dark theme automatically.\n\n- area-chart.tsx: colorTo\n[…]\nused for a \"+X% above avg\"\n  stat that isn't negative — should read text-pos like the sibling\n  TokenTrendSummary card\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): redesign analytics to design-system v2 tokens",
          "author_name": "Duyet Le",
          "author_login": "duyet",
          "committed_at": "2026-07-02T04:33:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "29e236dfa3981b2418577a5f97b17c78e25cf9d2",
          "body": "feat: merge redesign/v2 (design-system v2 + API reference reconcile) into main",
          "is_bot": false,
          "headline": "Merge pull request #245 from duyet/redesign/v2",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T04:20:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d7178fd9e1b0f6aebccf23673ff02321e24d6961",
          "body": "# Conflicts:\n#\tdocs/INDEX.md\n#\tdocs/api-reference.md\n#\tpackages/dashboard/src/layouts/MarketingLayout.astro\n#\tpackages/dashboard/src/styles/tokens.css",
          "is_bot": false,
          "headline": "Merge remote-tracking branch 'origin/main' into redesign/v2",
          "author_name": "Duyet Le",
          "author_login": "duyet",
          "committed_at": "2026-07-02T04:17:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "67b38024b0ef1a6b8e9776b38ac081a9ed0dbb66",
          "body": "* feat(dashboard): migrate marketing scope to design-system-v2 fonts\n\nRetire Geist from the marketing/brand scope and unify on the v2 type\nsystem already used by the dashboard: Space Grotesk (display),\nHanken Grotesk (body), JetBrains Mono (code).\n\n- tokens.css: swap @theme font families, add --font\n[…]\nine collapsing surfaced by the\npre-commit hook. No logic changes.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "style: apply biome formatting to api and sdk sources (#244)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T04:16:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "86ef71cdfce3fc133426c197ca08e79d8ff7e1e8",
          "body": "The api-reference \"Current API\" section documented a never-deployed \"v2\"\nbehavior (PATCH updates, ?include=messages, pagination.total, messages\nexcluded from create, 204 on append, timestamp message cursors, key_id/\nproject_id field renames, project_id analytics query param). The v2 router\nwas remov\n[…]\nion analytics, bulk delete, export, tags,\n  AI features, dashboard project views)\n- Rewrite docs/v2-migration.md as a short historical note; fix INDEX.md link\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs: reconcile API reference with the live /api/v1 router (#243)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T04:13:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "200bd9bec4c632b05406f262c7a468f2c2861b5d",
          "body": "…241)\n\nRetire Geist from the marketing/brand scope and unify on the v2 type\nsystem already used by the dashboard: Space Grotesk (display),\nHanken Grotesk (body), JetBrains Mono (code).\n\n- tokens.css: swap @theme font families, add --font-display\n- MarketingLayout: load the new @fontsource-variable packages\n- brand.astro: relabel the type specimen (Display/Sans/Mono) so it\n  accurately describes the fonts the page now renders\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): migrate marketing scope to design-system-v2 fonts (#…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T03:57:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c8be76b2bec87fc531bebed9050160fa8d71f61",
          "body": "…ids (#238)\n\n* fix(api): tighten input validation for slugs, tags, and conversation ids\n\n- Project slugs now have a 255-char upper bound (previously unbounded)\n- Unify conversation-tag and state-tag max length to 50 chars via a\n  shared TAG_MAX_LENGTH constant, replacing the inconsistent 50 vs 64\n  \n[…]\not <bot@duyet.net>\n\n* style(api): biome format after merging main\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): tighten input validation for slugs, tags, and conversation …",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T03:54:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "af3bbbd92908d816c43d63d3a4f4b6698ad7b3b1",
          "body": "…ns (#239)\n\nAudit unit A2 (V2 keys security + minor consistency):\n\n- Finding 1 (CRITICAL, keys route missing scope enforcement) was already\n  fixed upstream: the unmounted routes/v2/keys router this finding targeted\n  was removed entirely by #228's v2->v1 collapse, and the live route\n  (routes/v1-ke\n[…]\n the RFC 6749\n  { error, error_description } shape instead of the standard API error\n  format, and that the rest of the oauth router uses the standard format.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(api): document keys/leases/states/webhooks/oauth scope conventio…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T03:52:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cec40c0c2fd14b928a6233036f644ec623ffcf47",
          "body": "- environment-variables.md: fix VECTORIZE_INDEX / STATE_STREAM_HUB\n  references from stale /v2/* paths to the real mounted paths\n  (GET /api/v1/conversations/search, GET /api/v1/states/watch)\n- api-reference.md: add total_cost_microdollars and total_tokens to\n  conversation response examples and the\n[…]\n() and the create handler serialization\n- docs-data.ts: fix conversation update method PATCH -> PUT to match\n  the mounted routes/conversations/crud.ts router\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs: correct stale route paths and missing response fields (#235)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T03:51:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f6b10804e6cd3883c9e7d934713e64ea6e78881e",
          "body": "Merge docs/integration-guide.md into the canonical docs/integration.md\n(the more widely referenced file) and turn the former into a short\npointer. Preserves all unique content: chat-app patterns, LLM tracing,\nmulti-tenant SaaS, full REST reference, AI SDK UI/RSC stores, Cloudflare\nAgents SDK, generi\n[…]\nardize base URL and as_live_ + 40 base62 key format.\n- Update internal links in INDEX.md (dedupe the two entries) and\n  integrations/clickhouse-monitoring.md.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs: consolidate integration guides + add LangChain example (#234)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T03:51:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d5a4c166a6bf334aac92deed3c843e24e5521d70",
          "body": "…mples (#233)\n\n- Clarify that https://agentstate.app/api (TS default) and\n  https://api.agentstate.app (Python default) are equivalent aliases,\n  documented in docs/sdk.md, python-sdk README, and client.py docstring.\n- Add a message response-shape example to docs/sdk.md showing the real\n  fields the API returns (model, input_tokens, output_tokens, metadata),\n  matching deserializeMessage in packages/api/src/lib/serialization.ts.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(sdk): align SDK base-url notation and complete message-field exa…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-07-02T03:51:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3bfeb48041c08415de3147647b05c5f5087d35ab",
          "body": "…foundation' into redesign/v2",
          "is_bot": false,
          "headline": "Merge remote-tracking branch 'origin/feat/dashboard-design-system-v2-…",
          "author_name": "Duyet Le",
          "author_login": "duyet",
          "committed_at": "2026-07-02T03:22:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a96906c91189e4d246a8119781d81ac4762ce8cc",
          "body": "Merge tokens.css and global.css's competing color/type systems into one\nsource of truth. tokens.css is now the canonical @theme (vermilion accent\nreplaces blue, unified on Space Grotesk/Hanken Grotesk/JetBrains Mono,\nretiring Geist); global.css imports it and layers shadcn-style aliases\n(bg-card, te\n[…]\npec for downstream page workers: token\nnames, type/spacing/radius scale, primitive component APIs, and do/don't\nrules.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): unified design-system v2 foundation",
          "author_name": "Duyet Le",
          "author_login": "duyet",
          "committed_at": "2026-07-02T03:09:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b3e77dea879977171db62a8d8e9a6677004efef7",
          "body": "Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): update dependency node to v24 (#232)",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-06-30T00:09:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd4dddcab86d369de9382de4afd92fa47e72dd92",
          "body": "Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): update dependency @types/node to v26 (#231)",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-06-30T00:08:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "54aa2426d594bebcdbd23aa92c61a78187f87283",
          "body": "Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): update astro monorepo (major) (#230)",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-06-23T00:08:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d3de5878ff3eda07061cd7cabdafdcc5ad59938b",
          "body": "Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(deps): update actions/checkout action to v7 (#229)",
          "author_name": "renovate[bot]",
          "author_login": "renovate[bot]",
          "committed_at": "2026-06-23T00:07:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ec68b8b222e5fdcafa67a0b0ed31c39006aef914",
          "body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(main): release 0.1.4 (#176)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-06-21T04:16:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61af5f4aeba1e5cfc5d5145641c0ef79ec051b8a",
          "body": "…el stack (#228)\n\nRemoves the unmounted routes/v2 trees, orphaned semantic-search plumbing, the\nduplicate v2-projects service (updateProject inlined into services/projects),\nstale v2 *.skip.ts suites, the orphaned analytics service, and callerless\nhelpers. Flattens routes/v2 into routes/ and renames v2-conversations to\nmcp-conversations. No behavior change; 327 tests pass.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "refactor: finish the v2→v1 collapse — remove the dead \"API v2\" parall…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-20T06:15:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1dc75aabce2fd6fee11b5ec20e6329fde35e6abe",
          "body": "…laim:write) (#227)\n\nThe scoped-keys taxonomy used plural `leases:write` / `claims:write`, but the\npre-existing convention — the v2 lease/claim route guards (scopedAuth), the\ncapability-token scopes, and already-issued as_cap_ tokens — uses singular\n`lease:write` / `claim:write`. The mismatch meant \n[…]\nonical scope form across keys, capability tokens,\nroutes, and MCP — no mapping.\n\nAdds a regression test: a key scoped to lease:write can use the leases route.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): standardize lease/claim scopes to singular (lease:write / c…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T12:24:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a12fe9e812cd40f361d013f1369c0b27aa8cf484",
          "body": "Adds create_api_key, list_api_keys, and revoke_api_key tools so MCP clients can\nmanage project API keys (with scopes) directly — matching the hosted remote MCP\nserver. They call the keyless /api/v1/keys endpoints (project from the auth\ncontext). create_api_key enforces the subset-of-caller scope rul\n[…]\nde.\n\n- src/index.ts: 3 new tools + an apiScopeSchema enum of the API scopes\n- tests: cover the new tools' request URL/method/body\n- README: list the new tools\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(mcp): add API-key management tools to the stdio MCP server (#226)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T12:09:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "985de3d93f53b45c6889f82e7c54aa004f35c0e3",
          "body": "… connect (#225)\n\n- API key creation: \"Full access\" (default) vs \"Custom\" permission selector with\n  a grouped scope checklist; keys table shows per-key permission badges\n- New OAuth consent screen at /oauth/consent (Clerk-gated): shows the requesting\n  client, requested scopes, and a project select\n[…]\nsection with the hosted MCP URL and config\n  snippets for token auth and OAuth\n- Shared dashboard scope catalog (src/lib/scopes.ts) mirroring the API taxonomy\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): scoped-key permissions UI, OAuth consent screen, MCP…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T12:01:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8c7932dabfba2a1b6872174676acf422f28b2dd2",
          "body": "Document the hosted remote MCP server at POST /api/mcp (Bearer token or\nOAuth), the OAuth 2.1 + PKCE flow with discovery and consent, and scoped\nAPI keys.\n\n- docs/mcp.md: add \"Remote MCP server (hosted)\" section, keep local stdio below\n- docs/oauth.md: new — discovery, DCR, authorize/consent/token, \n[…]\novery, scopes field, /api/v1/keys\n- dashboard /docs: add Remote MCP, OAuth, Permissions sections + nav\n- packages/mcp/README.md: note the hosted remote server\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs: remote MCP server, OAuth 2.1, and key permissions (#222)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T11:48:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "42a2323de6e3a8629b7ffd336ea0f1ffc9a8868a",
          "body": "…tes (#224)\n\nAdd a stateless Streamable HTTP MCP server (spec 2025-06-18) at POST /api/mcp\nso agents can connect over the network with an AgentState API key or an\nOAuth/capability access token, instead of running the local stdio bridge.\n\n- middleware/mcp-auth.ts: accepts `as_live_` keys and `as_cap_\n[…]\n/list, tools/call, scope\nenforcement, capability-token lease delegation, protocol-version negotiation,\n401 challenge, and 405 on GET. Full suite: 302 passing.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(api): remote MCP server at /api/mcp + keyless key-management rou…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T11:46:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5517c4b5e6c080ae9a85621bd3f3ad4abf596d0c",
          "body": "…(#223)\n\nCo-hosts an OAuth 2.1 (authorization-code + PKCE S256) server in the Worker so\nMCP clients can obtain scoped access tokens. Access tokens reuse the existing\ncapability-token mechanism (as_cap_ tokens), so they validate through the\nexisting scopedAuth path unchanged.\n\nEndpoints:\n- GET /.well\n[…]\n\nconsent decision incl. cross-org rejection, full code exchange, PKCE mismatch,\ncode replay, refresh rotation + reuse rejection). Full API suite: 317 passing.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(api): OAuth 2.1 authorization server + discovery for remote MCP …",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T11:39:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "29b28373087d9feb6a182328de9eb35f9b83173f",
          "body": "Add a permission-scope model to API keys so a key can be restricted and can\nonly mint child keys/tokens within its own scopes — the foundation for the\nremote MCP server + OAuth consent work.\n\n- lib/scopes.ts: canonical API_SCOPES taxonomy + scopeSatisfies /\n  scopesSatisfyAll / effectiveKeyScopes he\n[…]\n rate limit + webhooks:write\n- shared: ApiKeyResponse.scopes + ApiScope type\n\nLegacy/unscoped keys resolve to full access (\"*\") so existing keys keep working.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(api): scoped API keys foundation (permissions + enforcement) (#221)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T11:07:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8c7a57c9fe989f984d39f56bd3bef64115362819",
          "body": "… sidebar project scope (#220)\n\n* fix(dashboard): repair delete-project and retention confirmation dialogs\n\nBoth reused DialogTrigger (a self-contained component) alongside their own\nopen-state + Dialog, producing a phantom modal showing only the trigger's\nicon + label. Retention was worse: its Chan\n[…]\n.json, plus an `npx skills add duyet/agentstate`\ninstall snippet.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(dashboard): dialogs, traces auth, markdown, project sort + global…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T09:06:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "63f7fc2b216740f3d5e675b78ef7f1e85c36a44d",
          "body": "… $NaN cost (#219)\n\nThe project Data tab rendered every message as a role badge + raw text, so\nassistant markdown showed literal **bold**, ### headings, and * bullets, and\nthe cost column showed \"$NaN\".\n\n- Render messages as a chat (assistant-ui style): user messages in a\n  right-aligned bubble; ass\n[…]\non-finite as\n  $0.00 (the conversation list API omits per-conversation cost).\n\nNew deps: react-markdown@10, remark-gfm@4 (client-only, in the message island).\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): chat-style conversation rendering with markdown; fix…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T06:52:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c09606399193e8d1ba96803226a0fa7985d2bcc2",
          "body": "…evoke) (#218)\n\nThe members page could only display members and pending invitations —\nrevoking an invitation punted to the Clerk Dashboard and there was no way\nto remove a member or change a role in-app.\n\nAdd admin-only management via Clerk's client SDK (which enforces admin\nauthorization server-sid\n[…]\ning state.\n\nNo backend/auth changes — all actions go through Clerk. Org data is already\nscoped by the session's active org, so members see shared org content.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): in-app org member management (remove, role change, r…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T06:42:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1f635a3c50c12e709acf2b0aa418c423444a3c34",
          "body": "… nav links (#217)\n\nTwo related dashboard fixes:\n\n1. `text-base` was used as a color (with `bg-fg`) in the primary button and\n   landing-page CTAs, but Tailwind reads `text-base` as a font-size utility, not\n   the `--color-base` token. The text color fell back to the inherited muted\n   body color → \n[…]\nnks with an external-link affordance, are never\n   highlighted as active (removed from active-URL resolution), and are pinned to\n   the bottom of the sidebar.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(dashboard): correct primary-button text color + restyle secondary…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T06:30:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bf510136d12cd223743c9d30c2a1a4c5e1edf229",
          "body": "…(#216)\n\nThe projects list only showed name, key count, and created date. Add\nper-project aggregates — conversations, messages, tokens, and last\nactivity — plus a name/slug filter input above the table.\n\n- API: listProjects now returns conversation_count, message_count,\n  total_tokens, and last_acti\n[…]\nhe four stat fields.\n- dashboard: new responsive columns (secondary columns hide on smaller\n  viewports) and a client-side filter; empty-match state included.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): show per-project stats and filter in projects table …",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T05:57:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2b8d1e0099891a555394e8a25653a608b5120583",
          "body": "The sidebar used per-item exact matching, so detail routes like\n/dashboard/project (where the projects table links) matched no nav\nentry and left nothing highlighted. Replace with longest-prefix\nmatching: a child route resolves to its closest parent (Projects),\nwhile deeper exact matches (Conversations, Analytics) still win, and\nthe root \"/\" only matches the root path.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(dashboard): highlight correct sidebar item on child routes (#215)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T05:54:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "02bc74b5aa73bd559c449ebda636d63814c9a323",
          "body": "…) (#214)\n\nAdds honest `biome-ignore: used in the template below` to the page-component and\nDashboardLayout imports on the seven dashboard app pages (analytics,\nconversations, domains, index, integrate, project, create-org). Biome can't see\nAstro template usage, so it flagged these as unused — but e\n[…]\n. Completes the QUAL-2 cleanup for the app pages; these 7 files now lint\nclean.\n\nRisk: 🟢 comments only, zero output change (build 13 pages). Rollback: revert.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "chore(dashboard): silence import false-positives on app pages (QUAL-2…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T04:44:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d28ca7290892e434721f1aa9f8ebe6050d4fa1aa",
          "body": "Silence the recurring biome warnings without changing any rendered output:\n- Remove 4 ineffective JSX biome-ignore comments (conversations-page, _table-\n  skeleton ×2, _keys-tab) that biome reported as having no effect (misplaced /\n  rule not firing).\n- Fix the global.css reduced-motion override: mo\n[…]\ning\nrendered was removed). Dashboard biome warnings 68 → 48. No behavior change.\n\nRisk: 🟢 comments only, zero runtime/output change. Rollback: revert this PR.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "chore(dashboard): clean up lint-debt suppressions (QUAL-2) (#213)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T04:34:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e903d4569779238a55b42aa1c6acf2a63f134e92",
          "body": "… (#212)\n\nAdds a comparison section to the landing page contrasting AgentState with\nmemory/history-only tools and roll-your-own setups. A 6-row table covers\nconversation history, versioned state, distributed leases, capability tokens,\nverifiable claims, and pricing/hosting — emphasizing the coordina\n[…]\nw deps. Visually verified\n(desktop + mobile; table wraps without overflow; dark = token-only). Sections\nabove/below intact. Rollback: revert this single file.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): add \"vs memory-only tools\" comparison section (LP-3)…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T04:34:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a77bbee08cd39b63f3748131e58210b5eefc632d",
          "body": "Introduce a minimal AIProvider interface (generateTitle, generateFollowUps,\ngenerateTitleAndFollowUps, generateEmbedding) with WorkersAIProvider as the\ndefault implementation. The existing logic (models, prompts, parsing) is MOVED\nverbatim from ai.ts into the provider; the exported service functions\n[…]\n same parsing/fallbacks; vitest 280/280 unchanged.\n\nRisk: 🟢 behavior-preserving extraction; no call-site or API change, no new deps.\nRollback: revert this PR.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "refactor(api): extract AIProvider seam over Workers AI (DEHARD-2) (#211)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T04:19:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "03d149e29c034e63412d74e6b84e7325e608c751",
          "body": "The public pages had a stale title/description and no social/canonical meta;\nsitemap.xml 404'd. This adds proper SEO to the marketing surface:\n\n- MarketingLayout now accepts title/description/ogImage/canonical props and emits\n  <title>, meta description, OpenGraph, Twitter Card (summary_large_image)\n[…]\n/twitter:card/canonical; sitemap emitted to out/.\n\nRisk: 🟢 additive head meta + one static file; no body/layout change, no new deps.\nRollback: revert this PR.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): SEO meta + sitemap for marketing pages (LP-4) (#210)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T04:17:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dc0aaf482c4c646a1b71093dfbe2b6c71be7bd4a",
          "body": "…ets (LP-1) (#209)\n\nThe homepage hero undersold the product — \"The state layer for AI agents\" with a\nmemory/adapters framing read like a chat-history store, not a coordination layer\nfor multi-agent systems. The README already had the right message; this aligns\nthe homepage with it.\n\n- H1: \"State & c\n[…]\nno new deps/components. Visually\nverified (build 13 pages; light desktop+mobile+full-page screenshots; dark = same\ntokens). Rollback: revert this single file.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(dashboard): reframe landing hero around coordination & agent fle…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T04:01:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a4dee462bea72d4c28a6cf05a6d83f56fcd7b07a",
          "body": "Documents @agentstate/mcp (shipped in #207): prerequisites, npx/global install,\nenv vars (AGENTSTATE_API_KEY, AGENTSTATE_BASE_URL), ready-to-paste mcpServers\nconfig for Claude Desktop / Cursor / Windsurf, the 12 tools grouped by primitive,\na \"verify it works\" step, and a free-key CTA. Linked from do\n[…]\nDEX.md.\n\nEvery tool/env documented was checked against packages/mcp/src/index.ts — no\nfabricated tools or flags.\n\nRisk: 🟢 docs-only. Rollback: revert this PR.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(mcp): add MCP server install & usage guide (MCP-2) (#208)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T04:00:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b7b6429bcf2779b1eda3000e1858faa0ebf27f9e",
          "body": "…tives (MCP-1) (#207)\n\nNew package that lets agents use AgentState from Cursor / Claude Desktop /\nWindsurf via the Model Context Protocol. Self-contained stdio server built on\n@modelcontextprotocol/sdk; talks to the AgentState REST API over fetch (no\nworkspace coupling). Tools: store/recall/list con\n[…]\nkey.\n\nRisk: 🟡 new package; not imported by api/dashboard so zero production runtime\nimpact. Rollback: revert this PR (removes the package + lockfile entries).\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(mcp): add @agentstate/mcp — MCP server exposing AgentState primi…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T03:46:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "709015b0e5bbf74b272afb87477936d2964d5dbd",
          "body": "…D-1) (#206)\n\nExtract scattered magic numbers (cache TTLs, lease default TTL, retention\nbatch size + time budget, ms-per-day) into a single lib/config.ts module so\nthe values have one authoritative home. Pure refactor — every constant keeps\nits exact prior value; behavior is byte-identical (vitest 2\n[…]\nliberately left next to their security-critical\nlogic (protected code, human-gated).\n\nRisk: 🟢 none (no runtime behavior change). Rollback: revert this commit.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "refactor(api): centralize tunable constants into lib/config.ts (DEHAR…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T03:45:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "625efe240bb6afbc4f2945f998b46f0a24df6cae",
          "body": "* chore(content): add generator for served llms.txt/agents.md content\n\nstatic.ts is served at /llms.txt and /agents.md but was hand-maintained despite an\n'auto-generated' header. Add scripts/generate-content.mjs (bun run gen:content) so it\ncan no longer drift from the source files.\n\nCo-Authored-By: \n[…]\nlds=!messages omits).\n- Regenerate served static.ts from the sources.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyet <me@duyet.net>",
          "is_bot": false,
          "headline": "docs: make AI-agent integration content accurate and complete (#183)",
          "author_name": "duyetbot",
          "author_login": "duyetbot",
          "committed_at": "2026-06-18T02:15:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "91a831c8ce3a92c6540d01ea2c958fe8d89fb43a",
          "body": "POV post on attesting agent output with claims + text_hash/json_value/\nstate_event evidence and the verify flow. All API shapes grounded in\ndocs/recipes/claims.md and the claims service; no fabricated metrics. (CONTENT-2)\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(blog): verifiable agent output with claims and evidence (#203)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T02:06:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5880bee5f543dde3ad45c4be7d048a05b7066704",
          "body": "…(#204)\n\ngetting-started: drop the broken keyless \"create project via curl\" example\n(project creation requires dashboard/Clerk auth) and point to dashboard signup;\nadd a leases-recipe pointer. README: fix dashboard dev port (3000->4321) and use\n$CONVERSATION_ID in the retrieve example. Accuracy verified vs /api/v1 routes.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs: tighten 2-minute quickstart + fix stale references (CONTENT-4) …",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T02:06:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b6b36739ca071e2d96f914ff0fc9f72b1d266598",
          "body": "…ouble-release (QUAL-3) (#205)\n\nAdds 5 tests (audited existing v2-* coverage first; these were genuinely\nmissing): expired lease re-acquisition with strictly higher fencing token\n(+ active lease still blocks with 409), expired capability token -> 401\n(+ valid token authenticates), double-release lease -> 404. Deterministic\nvia DB-level expiry (no real sleeps). 280 tests pass.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "test(api): coordination edge cases — lease eviction, expired token, d…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T02:05:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5844c896cff0b351919d15bf5e7882890826b375",
          "body": "…ems (#201)\n\nCategory POV post mapping multi-agent coordination needs to AgentState\nprimitives (leases/claims/capability-tokens/states). Claims grounded in\nreal /api/v1 routes; no fabricated metrics. (CONTENT-3)\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(blog): why agent memory tools aren't enough for multi-agent syst…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T01:46:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e7866be32946ff99ee146b6808cfc36d2a73a5d3",
          "body": "The migration guide's body contradicted its own \"all v1 now\" banner and\ndocumented /api/v2 paths that 404. Reconcile to the real /api/v1 routes;\nground deprecation/sunset claims in lib/deprecation.ts — no routes\nactually call setDeprecationHeaders in production. Frame the v2 proposal\nsections clearly as historical reference. (DOC-4)\n\nCo-authored-by: Duet Le <me@duet.net>\nCo-authored-by: duyetbot <bot@duet.net>",
          "is_bot": false,
          "headline": "docs: align v2-migration guide with unified /api/v1 reality (#200)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T01:46:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6cb57ed91f6771911fe018399ed8afb0b1b109db",
          "body": "Type-only changes — db→DrizzleD1Database, executionCtx→ExecutionContext,\nremove unsafe casts. No behavior change; 275 tests still pass. (QUAL-4)\n\nCo-authored-by: Duet Le <me@duet.net>\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "refactor(api): replace `any` with precise types in services (#202)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T01:46:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f626ee3e31afaa62fa7d0901c11bcd91d2708df1",
          "body": "…ases (CONTENT-1) (#199)\n\nAdd docs/blog/ with an index and the first post: a runnable walkthrough of the\nlease primitive for exactly-once processing across an agent fleet (curl + TS\nSDK). All /api/v1 endpoints, the 409 LEASE_CONFLICT code, SDK method names, and\nfencing-token semantics verified against the codebase; links to the\nexamples/fleet-leases script.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(blog): scaffold + first post — coordinating agent fleets with le…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T01:11:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "90476da3e815baf882e25efa7001e979fb432a0c",
          "body": "Add a Primitives section to docs/sdk.md with a short, runnable\nTypeScript snippet for each of the five primitives (States, Leases,\nCapability Tokens, Claims, Conversations). All method names verified\nagainst packages/sdk/src/index.ts — no invented APIs.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(sdk): runnable per-primitive usage snippets (SDK-3) (#196)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T00:50:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "81f027c7a31b72a0834fd7489411d98cc7ecb790",
          "body": "Add a \"never commit secrets\" section, document all Worker bindings\n(required + optional), Worker secrets (CLERK_SECRET_KEY, CLERK_JWT_KEY),\nwrangler vars tuning knobs (RATE_LIMIT_MAX, PROJECT_CREATION_RATE_LIMIT_MAX),\nand the RATE_LIMITS / VECTORIZE_INDEX / STATE_STREAM_HUB optional bindings\nthat were absent from the previous version.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(security): secret-scan sweep + env handling guide (SEC-1) (#198)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T00:48:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a1161b7b26cd93a2e5176f836a609f5f9c1516f",
          "body": "Add a prominent markdown table near the top of docs/INDEX.md listing\nthe five coordination primitives (States, Leases, Capability Tokens,\nClaims, Conversations) with one-line descriptions and links to each\nrecipe file.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(index): 5-primitives table linking each recipe (MSG-2) (#195)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T00:43:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a02b04b4483981728f9c1c2f29cc9a6891c5c7e",
          "body": "…o /api/v1 (#194)\n\n* fix(api): restore project retention PATCH — converge /api/v/ scar onto /api/v1\n\nThe /api/v2/→/api/v1/ rename swept the backend (index.ts + tests) but not\nthe dashboard, leaving project-management mounts at the version-less\n/api/v/projects. The dashboard's retention setting calle\n[…]\nession test to assert `id` is\npresent and `project_id` is absent.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(api): restore project retention PATCH — converge /api/v/ scar ont…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-18T00:35:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b31a7dabd0587a8b7f7b691431b282b9fe8f1d9b",
          "body": "…rites (EX-1) (#193)\n\n* feat(examples): add fleet-leases example (coordinate N agents, zero double-writes)\n\nA runnable script spawning K workers that coordinate via leases so each\ntask is processed exactly once; asserts zero double-processing. Reads\nAGENTSTATE_API_KEY from env. Implements EX-1.\n\nCo-\n[…]\nase\nand concurrent workers double-process, failing the assertion.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(examples): fleet-leases — coordinate N agents with zero double-w…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T19:32:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "11e7bea5b8ce6534ab64ab31535584f940ba0a38",
          "body": "* docs(trust): add data-handling & data-ownership guide\n\nDocuments what data is stored, export (\"your data is yours\"), deletion\nand control, actual retention behavior, data security, and the\nself-host option. Verified against schema and routes. Implements TRUST-3.\n\nCo-Authored-By: Duyet Le <me@duyet\n[…]\ns)\n\nCorrect three endpoint references in the data-handling guide.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(trust): data-handling & ownership guide (TRUST-3) (#191)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T19:32:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e8f1de1dbf61b86a9148af2d48dcf01b7e416af1",
          "body": "Adds a securityHeaders middleware setting X-Content-Type-Options,\nX-Frame-Options, Referrer-Policy, and HSTS on every response (incl.\nerrors and static assets). Additive only — no change to auth, rate\nlimiting, or CORS. Implements SEC-2.\n\nCo-authored-by: Duyet Le <me@duet.net>\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "feat(api): add standard security response headers (#192)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T19:32:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7726b986f3539daf2435cfd686bf535d8ab5d4a0",
          "body": "… (#188)\n\nReframes the intro and Features so AgentState reads as the state &\ncoordination layer for agent fleets — States, Leases, Claims, Capability\nTokens, Conversations — with memory as one of five primitives rather\nthan the headline. Preserves badges, trust line, and docs table.\nImplements MSG-1.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(readme): lead with the coordination & state story (5 primitives)…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T19:12:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5f74b91a5b781bd6a8b305337dca0db51d5c752a",
          "body": "…) (#190)\n\nCompletes the five primitive recipes with runnable curl + TS/Python\nexamples for states (versioned event log, idempotency, time-travel,\nSSE watch) and conversations (CRUD, search, bulk, AI). Linked from\ndocs/INDEX.md. Implements backlog DOC (primitive recipes).\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(recipes): add states and conversations recipes (complete the set…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T19:12:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e87eb5415fd7d29f92e7872307cadcafec57fdfe",
          "body": "…cope denial (#189)\n\nAdds regression tests for the exactly-one-writer guarantee (lease\nacquire → 409 on contention → release → re-acquire with higher fencing\ntoken), json_value claim verification (pass + fail), and\ncapability-token scope denial on lease/claim writes. Implements QUAL-3.\n\nCo-authored-by: Duyet Le <me@duet.net>\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "test(api): cover lease contention/acquire, claim json_value verify, s…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T19:12:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6ba2d665b4eda5ee8495649f54fb8b8a9357171e",
          "body": "…lity tokens) (#186)\n\n* docs(recipes): add coordination primitive recipes (leases, claims, capability tokens)\n\nRunnable curl + TS/Python SDK recipes for the three coordination\nprimitives, each with key-concept notes. Linked from docs/INDEX.md.\nImplements backlog DOC-1/2/3 (Month-1 coordination wedge\n[…]\nx.HTTPStatusError (only 401/404/422/429 map to typed exceptions).\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(recipes): coordination primitive recipes (leases, claims, capabi…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T18:56:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a22c7210eda3fc9de0f6068cb69c023541f86875",
          "body": "Adds a public product roadmap (themes, no internal strategy) and\nminimal trust signals (MIT badge, self-host/free-to-start line,\nroadmap link) to the README. Implements backlog TRUST-4.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs: add public ROADMAP and OSS trust signals to README (#185)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T18:56:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aab0d49ac394e25aeed6c5fa0949d4c4af7d1377",
          "body": "* docs(security): add SECURITY.md responsible disclosure policy\n\nAdds a coordinated-disclosure policy (GitHub private reporting +\nfallback email), supported-versions note, scope, and a summary of\nexisting security practices. Implements backlog SEC-6.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Autho\n[…]\n\n/api/v1 is served) and drop an unverified runtime-secrets claim.\n\nCo-Authored-By: Duyet Le <me@duyet.net>\nCo-Authored-By: duyetbot <bot@duyet.net>\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "docs(security): add SECURITY.md responsible disclosure policy (#184)",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T18:56:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f1d451e4ac4a46ab0b887af8e76c77264440eb4f",
          "body": "… (#187)\n\ntsup's --dts build (rollup-plugin-dts) injects a `baseUrl` compiler\noption, which TS 5.9+ escalates to error TS5101 (deprecated, removed in\nTS 7.0). With CI on bun-version: latest, a recent TS bump turned this\ninto a hard failure: `bun run build` for the SDK fails, reddening main\nCI and bl\n[…]\net baseUrl ourselves — add\n\"ignoreDeprecations\": \"6.0\" to the SDK tsconfig so the dts build keeps\nworking across TS upgrades. No API or emitted-output change.\n\nCo-authored-by: duyetbot <bot@duyet.net>",
          "is_bot": false,
          "headline": "fix(sdk): silence injected baseUrl deprecation breaking the dts build…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T18:52:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ea3051f876e2ccd722a2d0950135e0f1ee362c65",
          "body": "…ons (#181)\n\n* chore(sdk): remove stale compiled artifacts from src/\n\nThe committed .js/.d.ts/.map files under packages/sdk/src shadowed the\nTypeScript sources under Vite's .js-before-.ts module resolution, causing\ntests that import ../src/index to run against stale output. The package\nonly ships di\n[…]\nc.com>\nClaude-Session: https://claude.ai/code/session_01AVRtn1t17iNe74i8ius8Ch\n\n---------\n\nCo-authored-by: duyetbot <bot@duyet.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sdk): add tag filter to listConversations for consumer integrati…",
          "author_name": "duyet",
          "author_login": "duyet",
          "committed_at": "2026-06-17T17:23:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "36ae481e97de103cbbdb4ced330931ead1bec6ac",
          "body": "Co-authored-by: duyet <me@duyet.net>",
          "is_bot": false,
          "headline": "docs: refresh SDK + API docs, fix v1/v2 README inconsistency (#179)",
          "author_name": "duyetbot",
          "author_login": "duyetbot",
          "committed_at": "2026-06-17T17:07:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 4,
      "commits_last_year": 452,
      "latest_release_at": "2026-06-21T04:16:59Z",
      "latest_release_tag": "v0.1.4",
      "releases_from_tags": false,
      "days_since_last_push": 4,
      "active_weeks_last_year": 12,
      "days_since_latest_release": 30,
      "mean_days_between_releases": 2.3
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": false,
      "has_contributing": true,
      "health_percentage": 57,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@agentstate/sdk",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "ai-agents",
            "agent-memory",
            "conversation-history",
            "langgraph",
            "vercel-ai-sdk",
            "mcp",
            "agent-state",
            "cloudflare-workers"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@agentstate/sdk",
          "is_deprecated": false,
          "latest_version": "0.1.4",
          "repository_url": "https://github.com/duyet/agentstate",
          "versions_count": 5,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 8052,
          "first_published_at": "2026-06-06T13:16:15.400000Z",
          "latest_published_at": "2026-07-17T03:41:11.417000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 4
        },
        {
          "name": "agentstate",
          "exists": true,
          "license": null,
          "keywords": [
            "ai",
            "agents",
            "state",
            "management",
            "firebase",
            "persistent",
            "storage",
            "real-time",
            "Development Status :: 5 - Production/Stable",
            "Intended Audience :: Developers",
            "License :: OSI Approved :: MIT License",
            "Operating System :: OS Independent",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.10",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Programming Language :: Python :: 3.9",
            "Topic :: Internet :: WWW/HTTP :: HTTP Servers",
            "Topic :: Scientific/Engineering :: Artificial Intelligence",
            "Topic :: Software Development :: Libraries :: Python Modules"
          ],
          "ecosystem": "pypi",
          "matches_repo": false,
          "registry_url": "https://pypi.org/project/agentstate/",
          "is_deprecated": false,
          "latest_version": "1.0.2",
          "repository_url": "https://github.com/ayushmi/agentstate",
          "versions_count": 3,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2025-08-21T13:55:17.347539Z",
          "latest_published_at": "2025-08-22T19:22:03.621675Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 333
        }
      ]
    },
    "popularity": {
      "forks": 1,
      "stars": 2,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-03-30",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 1,
        "total_forks": 1
      },
      "star_history": {
        "days": [
          {
            "date": "2026-06-05",
            "count": 1
          },
          {
            "date": "2026-06-15",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 2,
        "total_stars": 2
      },
      "open_issues_and_prs": 27
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples",
        "recipes"
      ],
      "has_llms_txt": true,
      "has_dockerfile": false,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "examples/fleet-leases/tsconfig.json",
        "packages/api/tsconfig.json",
        "packages/dashboard/tsconfig.json",
        "packages/mcp/tsconfig.json",
        "packages/sdk/tsconfig.json",
        "packages/shared/tsconfig.json",
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 65759,
      "source_files_sampled": 321,
      "oversized_source_files": 1,
      "agent_instruction_files": [
        "AGENTS.md",
        "CLAUDE.md",
        "packages/api/src/content/agents.md",
        "packages/dashboard/public/agents.md"
      ],
      "agent_instruction_max_bytes": 19307
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [],
        "collected": true,
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 5,
        "assessed_package": "pypi:agentstate@1.0.2",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@clerk/backend",
          "manifest": "packages/api/package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.7.0"
        },
        {
          "name": "drizzle-orm",
          "manifest": "packages/api/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.45.2"
        },
        {
          "name": "hono",
          "manifest": "packages/api/package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.12.21"
        },
        {
          "name": "nanoid",
          "manifest": "packages/api/package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.1.0"
        },
        {
          "name": "zod",
          "manifest": "packages/api/package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.24.0"
        },
        {
          "name": "zod-to-json-schema",
          "manifest": "packages/api/package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.25.2"
        },
        {
          "name": "@agentstate/shared",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "workspace:*"
        },
        {
          "name": "@clerk/react",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^6.6.6"
        },
        {
          "name": "@fontsource-variable/hanken-grotesk",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.2.8"
        },
        {
          "name": "@fontsource-variable/jetbrains-mono",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.2.6"
        },
        {
          "name": "@fontsource-variable/space-grotesk",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.2.8"
        },
        {
          "name": "@phosphor-icons/react",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.1.10"
        },
        {
          "name": "clsx",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.1.1"
        },
        {
          "name": "echarts",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^6.1.0"
        },
        {
          "name": "motion",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^12.38.0"
        },
        {
          "name": "next-themes",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.4.6"
        },
        {
          "name": "react",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "19.2.7"
        },
        {
          "name": "react-dom",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "19.2.7"
        },
        {
          "name": "react-markdown",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^10.1.0"
        },
        {
          "name": "remark-gfm",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.0.1"
        },
        {
          "name": "sonner",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.7"
        },
        {
          "name": "tailwind-merge",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.5.0"
        },
        {
          "name": "tw-animate-css",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.4.0"
        },
        {
          "name": "zod",
          "manifest": "packages/dashboard/package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.4.3"
        },
        {
          "name": "@modelcontextprotocol/sdk",
          "manifest": "packages/mcp/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.29.0"
        },
        {
          "name": "zod",
          "manifest": "packages/mcp/package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.25"
        },
        {
          "name": "httpx",
          "manifest": "packages/python-sdk/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.28.1"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "@clerk/backend",
            "direct": true,
            "version": "^3.7.0",
            "ecosystem": "npm"
          },
          {
            "name": "@clerk/react",
            "direct": true,
            "version": "^6.6.6",
            "ecosystem": "npm"
          },
          {
            "name": "@fontsource-variable/hanken-grotesk",
            "direct": true,
            "version": "^5.2.8",
            "ecosystem": "npm"
          },
          {
            "name": "@fontsource-variable/jetbrains-mono",
            "direct": true,
            "version": "^5.2.6",
            "ecosystem": "npm"
          },
          {
            "name": "@fontsource-variable/space-grotesk",
            "direct": true,
            "version": "^5.2.8",
            "ecosystem": "npm"
          },
          {
            "name": "@modelcontextprotocol/sdk",
            "direct": true,
            "version": "^1.29.0",
            "ecosystem": "npm"
          },
          {
            "name": "@phosphor-icons/react",
            "direct": true,
            "version": "^2.1.10",
            "ecosystem": "npm"
          },
          {
            "name": "clsx",
            "direct": true,
            "version": "^2.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "drizzle-orm",
            "direct": true,
            "version": "^0.45.2",
            "ecosystem": "npm"
          },
          {
            "name": "echarts",
            "direct": true,
            "version": "^6.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "hono",
            "direct": true,
            "version": "^4.12.21",
            "ecosystem": "npm"
          },
          {
            "name": "motion",
            "direct": true,
            "version": "^12.38.0",
            "ecosystem": "npm"
          },
          {
            "name": "nanoid",
            "direct": true,
            "version": "^5.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "next-themes",
            "direct": true,
            "version": "^0.4.6",
            "ecosystem": "npm"
          },
          {
            "name": "react",
            "direct": true,
            "version": "19.2.7",
            "ecosystem": "npm"
          },
          {
            "name": "react-dom",
            "direct": true,
            "version": "19.2.7",
            "ecosystem": "npm"
          },
          {
            "name": "react-markdown",
            "direct": true,
            "version": "^10.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "remark-gfm",
            "direct": true,
            "version": "^4.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "sonner",
            "direct": true,
            "version": "^2.0.7",
            "ecosystem": "npm"
          },
          {
            "name": "tailwind-merge",
            "direct": true,
            "version": "^3.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "tw-animate-css",
            "direct": true,
            "version": "^1.4.0",
            "ecosystem": "npm"
          },
          {
            "name": "zod",
            "direct": true,
            "version": "^3.24.0",
            "ecosystem": "npm"
          },
          {
            "name": "zod",
            "direct": true,
            "version": "^3.25",
            "ecosystem": "npm"
          },
          {
            "name": "zod",
            "direct": true,
            "version": "^4.4.3",
            "ecosystem": "npm"
          },
          {
            "name": "zod-to-json-schema",
            "direct": true,
            "version": "^3.25.2",
            "ecosystem": "npm"
          },
          {
            "name": "httpx",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "@astrojs/check",
            "direct": false,
            "version": "^0.9.9",
            "ecosystem": "npm"
          },
          {
            "name": "@astrojs/react",
            "direct": false,
            "version": "^6.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "@cloudflare/vitest-pool-workers",
            "direct": false,
            "version": "^0.18.0",
            "ecosystem": "npm"
          },
          {
            "name": "@cloudflare/workers-types",
            "direct": false,
            "version": "^5.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "@langchain/core",
            "direct": false,
            "version": "^1.1.49",
            "ecosystem": "npm"
          },
          {
            "name": "@langchain/langgraph-checkpoint",
            "direct": false,
            "version": "^1.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "@resvg/resvg-js",
            "direct": false,
            "version": "^2.6.2",
            "ecosystem": "npm"
          },
          {
            "name": "@rollup/rollup-linux-x64-gnu",
            "direct": false,
            "version": "^4.60.0",
            "ecosystem": "npm"
          },
          {
            "name": "@tailwindcss/vite",
            "direct": false,
            "version": "^4.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "@types/node",
            "direct": false,
            "version": "^26.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "@types/react",
            "direct": false,
            "version": "^19",
            "ecosystem": "npm"
          },
          {
            "name": "@types/react-dom",
            "direct": false,
            "version": "^19",
            "ecosystem": "npm"
          },
          {
            "name": "astro",
            "direct": false,
            "version": "^7.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "drizzle-kit",
            "direct": false,
            "version": "^0.31.10",
            "ecosystem": "npm"
          },
          {
            "name": "esbuild",
            "direct": false,
            "version": "0.28.1",
            "ecosystem": "npm"
          },
          {
            "name": "shadcn",
            "direct": false,
            "version": "^4.10.0",
            "ecosystem": "npm"
          },
          {
            "name": "tailwindcss",
            "direct": false,
            "version": "^4",
            "ecosystem": "npm"
          },
          {
            "name": "tsup",
            "direct": false,
            "version": "^8.5.1",
            "ecosystem": "npm"
          },
          {
            "name": "typescript",
            "direct": false,
            "version": "^5",
            "ecosystem": "npm"
          },
          {
            "name": "typescript",
            "direct": false,
            "version": "^5.7.0",
            "ecosystem": "npm"
          },
          {
            "name": "typescript",
            "direct": false,
            "version": "^5.9.3",
            "ecosystem": "npm"
          },
          {
            "name": "typescript",
            "direct": false,
            "version": "^6.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "vitest",
            "direct": false,
            "version": "^4.1.6",
            "ecosystem": "npm"
          },
          {
            "name": "vitest",
            "direct": false,
            "version": "^4.1.9",
            "ecosystem": "npm"
          },
          {
            "name": "wrangler",
            "direct": false,
            "version": "^4.93.0",
            "ecosystem": "npm"
          },
          {
            "name": "langgraph",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "langgraph-checkpoint",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "pytest",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-asyncio",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "respx",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "setuptools",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 57,
        "direct_count": 26,
        "indirect_count": 31
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 2,
        "merged_prs": 259,
        "open_issues": 25,
        "closed_ratio": 0.777,
        "closed_issues": 87,
        "closed_unmerged_prs": 18
      },
      "bus_factor": 1,
      "bot_contributors": 3,
      "top_contributors": [
        {
          "type": "User",
          "login": "duyet",
          "commits": 255,
          "avatar_url": "https://avatars.githubusercontent.com/u/5009534?v=4"
        },
        {
          "type": "User",
          "login": "claude",
          "commits": 156,
          "avatar_url": "https://avatars.githubusercontent.com/u/81847?v=4"
        },
        {
          "type": "User",
          "login": "duyetbot",
          "commits": 14,
          "avatar_url": "https://avatars.githubusercontent.com/u/101855044?v=4"
        }
      ],
      "contributors_sampled": 3,
      "top_contributor_share": 0.6
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "publish-sdk.yml",
        "release-please.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        "biome.json"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "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": 10,
            "reason": "28 out of 28 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 2/27 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 5 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 10,
            "reason": "security policy file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "28 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "9a12ed2e8c11f61bc1e42471c4b1c60b5182cb34",
        "ran_at": "2026-07-21T21:26:06Z",
        "aggregate_score": 4.8,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": true,
      "has_dependabot_config": false
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/duyet/agentstate",
    "host": "github.com",
    "name": "agentstate",
    "owner": "duyet"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 66,
      "inputs": {
        "security": 58,
        "vitality": 79,
        "community": 41,
        "governance": 65,
        "engineering": 82
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 79,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 72,
            "inputs": {
              "commits_last_year": 452,
              "human_commit_share": 0.92,
              "days_since_last_push": 4,
              "active_weeks_last_year": 12
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 4 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "12/52 weeks with commits",
                "points": 8.3,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 12
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "452 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 452
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 4,
              "latest_release_tag": "v0.1.4",
              "releases_from_tags": false,
              "days_since_latest_release": 30,
              "mean_days_between_releases": 2.3
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "4 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 30 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 30
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~2.3 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 2.3
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 41,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 1,
              "stars": 2,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "below_threshold"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "2 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "1 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "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": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "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": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 65,
            "inputs": {
              "packages": [
                "@agentstate/sdk"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 8052
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "8,052 downloads/month across npm",
                "points": 52.1,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 8052,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 65,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "at_risk",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 32,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 3,
              "top_contributor_share": 0.6
            },
            "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 60% of commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 60
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "3 contributors",
                "points": 4.1,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 5 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 72,
            "inputs": {
              "merged_prs": 259,
              "open_issues": 25,
              "closed_issues": 87,
              "issue_closed_ratio": 0.777,
              "closed_unmerged_prs": 18
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "78% of issues closed",
                "points": 36.3,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 78
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "259/277 decided PRs merged",
                "points": 35.8,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 259,
                      "decided": 277
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 2/27 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "good",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 70,
            "inputs": {
              "followers": 814,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "duyet",
              "public_repos": 544,
              "account_age_days": 4754
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "814 followers of duyet",
                "points": 20.9,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 814,
                      "login": "duyet"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "544 public repos, account ~13 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 544
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 13
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "@agentstate/sdk"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 4
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 4 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "5 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 82,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "4 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": "biome.json",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "biome.json"
                    }
                  }
                ],
                "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": "28 out of 28 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 80,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": "https://agentstate.app",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://agentstate.app",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 0,
                "status": "missed",
                "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": "moderate",
        "name": "Security",
        "value": 58,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": null,
            "notes": [],
            "value": 48,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 18,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 0,
              "scorecard_aggregate": 4.8
            },
            "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": "28 out of 28 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 2/27 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 5 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "28 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the pypi:agentstate@1.0.2 runtime dependency closure — what installing the published package pulls in — 5 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "pypi:agentstate@1.0.2",
                  "assessed": 5
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 5,
              "unassessed_packages": 0,
              "affected_by_severity": "none",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "no indirect dependency carries a known advisory",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "no_indirect_advisories",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 5,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 3
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 76,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "has_llms_txt": true,
              "legible_history_share": 0.989,
              "agent_instruction_files": [
                "AGENTS.md",
                "CLAUDE.md",
                "packages/api/src/content/agents.md",
                "packages/dashboard/public/agents.md"
              ],
              "agent_instruction_max_bytes": 19307
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md, CLAUDE.md, packages/api/src/content/agents.md, packages/dashboard/public/agents.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.md, CLAUDE.md, packages/api/src/content/agents.md, packages/dashboard/public/agents.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": "llms.txt present",
                "points": 15,
                "status": "met",
                "details": [
                  {
                    "code": "llms_txt_present",
                    "params": {}
                  }
                ],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "91 of 92 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 91,
                      "sampled": 92
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 54,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "examples/fleet-leases/tsconfig.json",
                "packages/api/tsconfig.json",
                "packages/dashboard/tsconfig.json",
                "packages/mcp/tsconfig.json",
                "packages/sdk/tsconfig.json",
                "packages/shared/tsconfig.json",
                "tsconfig.json"
              ],
              "agent_commit_share": 0.01,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0.07
            },
            "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": "biome.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "biome.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "examples/fleet-leases/tsconfig.json, packages/api/tsconfig.json, packages/dashboard/tsconfig.json, packages/mcp/tsconfig.json, packages/sdk/tsconfig.json, packages/shared/tsconfig.json, tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples/fleet-leases/tsconfig.json, packages/api/tsconfig.json, packages/dashboard/tsconfig.json, packages/mcp/tsconfig.json, packages/sdk/tsconfig.json, packages/shared/tsconfig.json, 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": "1 of the last 100 commits agent-authored or agent-credited",
                "points": 2,
                "status": "partial",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 1,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "7 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 7,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 65759,
              "source_files_sampled": 321,
              "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/321 source files over 60KB",
                "points": 54.8,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 321,
                      "oversized": 1
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "moderate",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 60,
            "inputs": {
              "example_dirs": [
                "examples",
                "recipes"
              ],
              "has_mcp_signal": true,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples, recipes",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples, recipes"
                    }
                  }
                ],
                "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": [
    "Could not fetch npm package '@agentstate/mcp' from its registry",
    "pypi package 'agentstate' points at a different repository (https://github.com/ayushmi/agentstate); excluded from ecosystem scoring"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-21T21:26:25.528564Z",
  "schema_version": "0.23.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/d/duyet/agentstate.svg",
  "full_name": "duyet/agentstate",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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