JSON-Rohbericht maschinenlesbar
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 3190,
"has_wiki": true,
"homepage": null,
"languages": {
"CSS": 11207,
"HTML": 380,
"Svelte": 638801,
"JavaScript": 49943,
"TypeScript": 1540325
},
"pushed_at": "2026-07-18T06:55:52Z",
"created_at": "2026-06-25T10:21:11Z",
"owner_type": "User",
"updated_at": "2026-07-18T08:18:20Z",
"description": null,
"is_archived": false,
"is_disabled": false,
"license_spdx": "MIT",
"default_branch": "main",
"license_spdx_raw": "MIT",
"primary_language": "TypeScript",
"significant_languages": [
"TypeScript",
"Svelte"
]
},
"owner": {
"blog": "https://gaubee.com",
"name": "Gaubee",
"type": "User",
"login": "Gaubee",
"company": "@BioforestChain ",
"location": "China-Fujian-Xiamen",
"followers": 100,
"avatar_url": "https://avatars.githubusercontent.com/u/2151644?v=4",
"created_at": "2012-08-14T15:36:14Z",
"is_verified": null,
"public_repos": 199,
"account_age_days": 5090
},
"license": {
"state": "standard",
"spdx_id": "MIT",
"raw_spdx": "MIT",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v1.4.2",
"kind": "patch",
"published_at": "2026-07-17T17:32:31Z"
},
{
"tag": "v1.4.1",
"kind": "patch",
"published_at": "2026-07-17T14:58:39Z"
},
{
"tag": "v1.4.0",
"kind": "minor",
"published_at": "2026-07-14T21:06:28Z"
},
{
"tag": "v1.3.1",
"kind": "patch",
"published_at": "2026-07-12T02:36:33Z"
},
{
"tag": "v1.3.0",
"kind": "minor",
"published_at": "2026-07-11T10:00:42Z"
},
{
"tag": "v1.2.0",
"kind": "minor",
"published_at": "2026-07-11T05:20:29Z"
},
{
"tag": "v1.1.0",
"kind": "minor",
"published_at": "2026-07-10T18:05:15Z"
}
],
"recent_commits": [
{
"oid": "43c3805cd20c97394b171201cb05f9b44cd60c1a",
"body": null,
"is_bot": false,
"headline": "feat(docs): add links to README.md",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-18T06:55:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c7ade95c9b2afbcb817ca360216212f5b8131111",
"body": null,
"is_bot": false,
"headline": "fix(tray): consume stable OpenTray WebView2 profiles",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-17T17:31:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7a5bb7aa442f1fa08f5c8ba16c3314f43ea99ac4",
"body": null,
"is_bot": false,
"headline": "fix(tray): expose menu transition completion",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-17T14:55:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "23985631ecdfe68f81cfa3eaec15e876ce4ae94b",
"body": null,
"is_bot": false,
"headline": "chore(release): publish 1.4.1",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-17T14:44:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d70ffc4a36d81634eb525cd3af9430db4a5056d3",
"body": null,
"is_bot": false,
"headline": "fix(tray): synchronize retained window visibility",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-17T14:41:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "84cbc1e13ffed4b7aa2acc6b9beecd511685c954",
"body": null,
"is_bot": false,
"headline": "chore(release): publish 1.4.0",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-14T21:01:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f2253200d162d9e9affb7f6d8b679f0ad40d22e7",
"body": null,
"is_bot": false,
"headline": "feat(webui): adopt OpenTray frameless controls",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-14T21:00:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "eeee95364dbc6a5eb8978a0bc7ea62adaaef8fa6",
"body": null,
"is_bot": false,
"headline": "chore(release): 发布 1.3.1",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T15:11:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c4a140ac17ba9cbf94fe2f23598e1f5b5108c06b",
"body": null,
"is_bot": false,
"headline": "fix: 加固应用升级异步任务边界",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T11:40:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d2982f35243f1a29c04ff007cfd470a9768a2af2",
"body": null,
"is_bot": false,
"headline": "feat: 完善应用升级日志与重启生命周期",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T11:03:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4c0638812f08673bbd3e1454cd79171a22d2c301",
"body": null,
"is_bot": false,
"headline": "chore(release): 发布 1.3.0",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T09:56:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1a96dfc4eaae8faaa0a9958e7bf2d7afea359e2f",
"body": null,
"is_bot": false,
"headline": "feat: 对齐 placeholder 发布与整包删除生命周期",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T09:46:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "32e2c29a67981006d730fc8c82699e0036b5a3c6",
"body": "新增 profile.otp RPC:守护进程用内存中的 totp_secret 经 otplib 生成 6 位\n动态码,返回 {code, remainingSec, epochMs, configured},密钥不离开 daemon\n(遵循 Chapter 3.1)。按 username 取密钥,并对任意已保存 profile 生效。\n\nWebUI 新增 otp-button 组件,置于 Profile 详情页右上角(仅激活 profile 显示):\n- tooltip open 由 pointerenter/pointerout 驱动,配合 disableCloseOnTriggerCl\n[…]\n 保证点击复制时 OTP 不被隐藏;未 open 时不拉取、不计时,并清空内存中的 code\n- tooltip 内用 grid 布局展示 ring | code;环形进度按 30s TOTP 窗口递减,\n 环心始终显示剩余秒数,最后 10s 弧线转为 warning 色\n- 点击复制 OTP,按钮短暂显示打勾图标;未配置 2FA 时按钮禁用并提示\n\n补齐 9 个 locale 的文案与翻译。",
"is_bot": false,
"headline": "feat: Profile 详情页接入 OTP 一键获取与复制",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T09:23:00Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "27c8433136fdf169072eb3ff02aab7a2c718a0cc",
"body": null,
"is_bot": false,
"headline": "fix(webui): 完善包详情 README 渲染与原生外链",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T07:29:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "758f00d09c43dcd817a63bbf9b97bcfec066326d",
"body": "type=\"single\" 的 ToggleGroup item 渲染 role=\"radio\" + aria-checked\n(aria-pressed 不渲染)。上次改用 data-state(on/off)虽能过测,但那是\nbits-ui 内部样式 hook 而非语义属性。改回 aria-checked(true/false)。\n\nCo-Refer: bits-ui toggle-group.svelte.js#ariaChecked/#ariaPressed",
"is_bot": false,
"headline": "test: 用语义属性 aria-checked 断言 ToggleGroup 选中态",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T05:26:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ba584bf0288f1f0fd0a3d8165ec77ff360c4243f",
"body": "Keep/Remove 按钮已迁移至 ToggleGroup(commit 59d5487),其选中态投影为\ndata-state(on/off)而非原先 ButtonGroup 的 aria-pressed(true/false)。\n更新浏览器断言读取 data-state;补 node 类型引用以通过 vp check。",
"is_bot": false,
"headline": "test: 对齐 trusted-publishing 移除评审为 ToggleGroup 语义",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T05:20:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d4459184279684ad52aa59f1bd980273c9d1d480",
"body": "该测试(原生 pnpm 子进程下 profile token 覆盖 project token)本地一致通过,\n但在 GitHub Actions Ubuntu 环境下失败。CI 特有的 userconfig/token 优先级\n行为需要单独排查,先 skip 以解除 1.2.0 发布阻塞。",
"is_bot": false,
"headline": "test: 跳过 CI 环境失败的 publish-userconfig 断言",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T05:12:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "89789e95c4c3f3518c8d52635a02b6a5622a7d04",
"body": "runtime-info 初始快照帧调用 keychain.activeService(),但 web-server-renew\n与 resolve-trust-auth 的 keychain mock 未导出该函数,导致快照生成器抛错、\nworkspaces 帧无法下发,re-broadcast 断言失败。",
"is_bot": false,
"headline": "fix(test): 为 keychain mock 补齐 activeService",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T04:57:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "79ed92a5be2e1a2740bca9aba30f738fed219c7e",
"body": null,
"is_bot": false,
"headline": "chore(release): 发布 1.2.0",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T04:35:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1572c73f5c6ac97e4360bab3d7a6e9795ac9909c",
"body": "- SWITCH PROFILE 下拉补全 AvatarImage,复用 avatarUrlFor 加载真实头像\n- add-profile 表单:label/input 间距改用 flex gap(规避 space-y 兄弟选择器\n 失效),空头像以 user-round 图标替代 ??,TOTP/密码改用 InputGroup 并将\n 扫码与显隐按钮置于 suffix,所有输入框统一 border-black/50",
"is_bot": false,
"headline": "fix(webui): 完善 add-profile 表单与 sidebar 头像绑定",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T04:35:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "76c80a9dcb92144ae3eaedbca61d738c56309c9e",
"body": "新增 add-profile-content 容器与 profile-import-form 原子,使 Add Profile\n与 Settings / Export 共享同一导入流程(本地校验、预览、选择后再下发密码\n与选中项给 Daemon)。Settings Export 标签页改为委托该原子,移除内联的\n导入状态机。同步接入 shadcn accordion / checkbox 组件并对齐 input 样式。",
"is_bot": false,
"headline": "refactor(webui): 抽取 profile-import 原子并复用于 add-profile",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T04:34:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2a8af193bba2f5ef3c17b9d6932d8706e9253fa0",
"body": "Daemon 通过 runtime-info 状态帧向 WebUI 投影 PID、平台、数据目录、\nprofiles.json、事件库与日志路径及凭据 service 名称,About 面板在折叠区\n展示这些诊断事实。路径由 Daemon 解析,正确反映 PNPM_PUB_HOME 覆盖;\n仅显示 service 名称,绝不投影凭据内容。",
"is_bot": false,
"headline": "feat(webui): 投影 Daemon 运行时信息至 About",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T04:34:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "740ad7fc089b2e5c292e59fb45816b64420e4d17",
"body": "移除 better-sqlite3 原生依赖,改用 Node 内置的 node:sqlite (DatabaseSync),\n统一 EventDb / RepoInfo / DaemonStore 的数据库交互。同步将构建目标、CI 运行时、\n文档要求提升至 Node 24,移除 onlyBuiltDependencies 中的 better-sqlite3 条目。",
"is_bot": false,
"headline": "feat(daemon): 迁移至 node:sqlite 并提升 Node 24",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T04:33:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5915d8b4660aa48b0de45e06bfc00a91bfc7f6a2",
"body": null,
"is_bot": false,
"headline": "chore(release): 准备 1.1.1",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T01:10:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "21000e1c11d1efc973445abbfb81c434949e7686",
"body": null,
"is_bot": false,
"headline": "fix(publish): 使用外部 userconfig 注入凭据",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T01:10:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e7f74408a4ecb5e3d5016ecee57b8cc94798796d",
"body": null,
"is_bot": false,
"headline": "docs(spec): 固化外部 userconfig 凭据注入法则",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-11T01:09:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1e96704f50e5999bf7227e3978839c52d8c8655d",
"body": "- 新增 shadcn-svelte 依赖,用于按需生成 Toggle/ToggleGroup/Tabs 等组件\n- layout.css 引入 shadcn-svelte/tailwind.css 基础样式",
"is_bot": false,
"headline": "chore(webui): 接入 shadcn-svelte 依赖与样式",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T19:22:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "59d5487f438aa508c6ac9620bf52472f3e423ee2",
"body": "- toggle.svelte 新增 primary/brand/destructive 变体,激活态改用强主色,\n 替代原先过淡的 bg-muted;default 不再自带激活样式\n- toggle-group-item 支持按 item 覆盖 group 的 variant/size(variant ?? ctx),\n 使单个 item 可独立采用 destructive 等语调\n- 将手写单选语义的 ButtonGroup 统一迁移:\n - settings/general-tab (Theme) -> ToggleGroup brand\n - event-card-body \n[…]\nGroup brand\n - trusted-publishing-removal-review (keep|remove) -> ToggleGroup,\n keep=brand / remove=destructive,消除手写 aria-pressed 与互斥状态\n- event-detail-dialog 的 inherit/customize 纯内容切换改用 Tabs(非表单值)",
"is_bot": false,
"headline": "refactor(webui): 将单选语义 ButtonGroup 迁移至 ToggleGroup/Tabs",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T19:21:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4ab1dac97029ac03770d1437ff328e7e533e1b17",
"body": null,
"is_bot": false,
"headline": "fix(release): 输出纯净版本到 Actions",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T18:01:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5f04586c9b7c5fbcb07bd15e7d4ece5a6d3f3f9f",
"body": null,
"is_bot": false,
"headline": "fix(test): 使用 Node 探测 Verdaccio 健康状态",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T17:31:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "02ccb861bb3c0092913442d9c9e4e52904c188a0",
"body": null,
"is_bot": false,
"headline": "fix(ci): 安装生产构建所需 Bun 运行时",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T17:24:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c0deb4cac3e6ceccf4b52e353cf7956ab75ffc19",
"body": null,
"is_bot": false,
"headline": "fix(test): 显式使用 Node WebSocket 客户端",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T17:19:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "af98f6f6b824954fe9a4805ef90200a7c6e61955",
"body": null,
"is_bot": false,
"headline": "fix(ci): 允许构建 better-sqlite3 原生绑定",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T17:14:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7460e90d8328776b9616e197ccd1f15ca92fbc90",
"body": null,
"is_bot": false,
"headline": "fix(ci): 统一 pnpm 与 Actions 运行时来源",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T17:12:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c3e04345139f729e939edc22a548c33f92429c63",
"body": null,
"is_bot": false,
"headline": "chore(release): 发布 1.1.0",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T17:10:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "26b98fae0ed17ffc40f745c07c52465281ff6ced",
"body": null,
"is_bot": false,
"headline": "fix(test): 隔离 unit 与 browser 测试通道",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T17:09:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a5268786daca0fdce91b444c7b0bbd897bd85721",
"body": null,
"is_bot": false,
"headline": "docs(spec): 固化测试通道隔离法则",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T17:06:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "40aedfc3f4c34cc02bd20f2bae2fd286ac4a503f",
"body": null,
"is_bot": false,
"headline": "fix(test): 对齐可信发布配置动作投影",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T17:01:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d22524e19ef6a8af561f0f76fe8c2e3c2ee36454",
"body": null,
"is_bot": false,
"headline": "feat(release): 使用 GitHub Actions OIDC 发布",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T16:55:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "30d43c7f83096bbc834de58724ab4462e4143042",
"body": null,
"is_bot": false,
"headline": "docs(spec): 定义 GitHub Actions 发布法则",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T16:53:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e187a53d9112d994694dcdb835ecf21b4e43f19f",
"body": null,
"is_bot": false,
"headline": "refactor(webui): 更新设置控件与组件基线",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T16:11:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cab715c1e68c4332773d810bf57d78d193b4b763",
"body": null,
"is_bot": false,
"headline": "feat(update): 添加应用内检查与显式更新",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T15:58:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "02906f2c3d8cdcef54c25329c835d2fdd70d0a5b",
"body": null,
"is_bot": false,
"headline": "fix(trusted-publishing): 持久化删除快照并默认全选",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T15:49:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e6ca2b61d5d7a91288de76552ef4a1e4c69bbb80",
"body": null,
"is_bot": false,
"headline": "docs(spec): 定义可信发布删除快照法则",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T15:17:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9bb3d765fd49522354e59402535dfe40721ced49",
"body": null,
"is_bot": false,
"headline": "docs: reorganize product documentation",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T03:58:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c23366f29e2bc5136121cc4cff9a31d3d8ebdc01",
"body": null,
"is_bot": false,
"headline": "fix(tray): keep add-profile visible on blur",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T03:41:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4c6c4b83428b5f931c94b245c8c5316f2e439207",
"body": null,
"is_bot": false,
"headline": "feat(dev): upgrade OpenTray DevTools support",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T03:39:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "068edb3841497934df0f388f2a1464093ea2618c",
"body": null,
"is_bot": false,
"headline": "fix(webui): preserve camera decoder geometry",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T03:27:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1b759b6a5796daafd304391aa28dffdf012f1100",
"body": null,
"is_bot": false,
"headline": "fix(webui): improve camera QR scanning",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-10T03:11:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c41d26d15b7058e4d69b05c1f99987c8954b6b29",
"body": null,
"is_bot": false,
"headline": "fix(test): 修复发布测试通道",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-09T17:07:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "af0642e0a0697781e484938c54d9290fc00b8dbe",
"body": null,
"is_bot": false,
"headline": "feat(build): 并发构建 cli 和 webui",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-09T14:57:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "27e89c8de568029a75fb8413b0cc520c6607650d",
"body": null,
"is_bot": false,
"headline": "fix(events): 区分 canceled 并接入 oidc 事件源",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T16:47:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2d4595ae989a78defeedf5a2ce547d1669dfd382",
"body": null,
"is_bot": false,
"headline": "fix(webui): 修正 advanced 参数投影",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T14:20:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2566616e302a55e8214e7cad8d9f27b8e60e00a9",
"body": null,
"is_bot": false,
"headline": "fix(cli): 安装入口 shebang + help 命令注册表",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T13:58:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3ff9ff23378ba2795291699de2666e68e4c17210",
"body": "Events footer 布局重构 + trust Dialog 本地暂存编辑 + i18n 系统化改造\n\n- Events 打开按钮从 header 迁到 footer(左右 cluster 对立)\n- Trust 成员 Dialog:三态按钮(关闭/放弃+保存)+ 模式/表单本地暂存\n- i18n:locale 按需加载 + 类型安全 + 键对齐检测 + 全量翻译 + CI strict\n- island:CSS 误报修复 + 冗余 toast 移除 + backdrop-filter 主题感知",
"is_bot": false,
"headline": "Merge branch 'feat/event-card-footer-actions'",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T13:04:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3479ede37a670fb80c8c7e12e106169febe7325d",
"body": "原实现:backdropFilter 作为字符串写死在 Motion 的 animate 对象里\n('blur(8px) contrast(0.8) brightness(1.2)'),contrast/brightness 是暗色\n模式专用值,亮色模式下错误。\n\n改为:\n- @property --island-blur 注册为 <number>,Motion 只动画 blur 半径数字\n (8/8/24),用 styleEffect/Motion 的 CSS 变量动画能力(WAAPI 需 @property\n 注册才能插值自定义属性,二者正好耦合)。\n- 完整 backdrop-fil\n[…]\n-island-grade 变量 + .dark 选择器切换:\n · 亮色(默认):contrast(2) brightness(0.8)——压亮背景内容保持可读\n · 暗色:contrast(0.8) brightness(1.2)——提升暗壁纸上的玻璃质感\n\n功能不变(blur 随 phase 平滑过渡),色彩分级正确响应明暗主题。\n\n验证:pnpm check 0/0,build 通过。",
"is_bot": false,
"headline": "fix(island): backdrop-filter 主题感知 + @property 数字动画",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T12:42:16Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b22b6de304268935916eb723e9d72f310989e8cc",
"body": "web-server.createProactiveEvent 成功后发了一个 'Pending event created —\nreview it under Events.' 的 info toast,经 bridgeDaemonToast 上岛。但新建\n的 pending 事件本身已经通过 +layout.svelte 的 pending-group 反射上岛\n(更丰富的 live-activity:摘要/详情/进度条/跳转卡片),这个 toast 只是\n冗余地竞争同一个 island 单槽。\n\n事件已上岛,无需再 toast 提示。直接删除该 toast 发送。\n\n(该字符串是硬编码英文,从未国际化——删除顺带消除一处未国际化字符串。)\n\n验证:typecheck 通过,webui check 0/0;测试 15 failed 为预存(stash 验证\n一致),与本次改动无关。",
"is_bot": false,
"headline": "fix(island): 移除创建事件时冗余的 'Pending event created' toast",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T12:24:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d2fd0803c0d1d6e5db235b9ea93df938b5e88f90",
"body": ".island / .island-detail / .island :global(svg) 写在 <motion.div>\n(@humanspeak/svelte-motion 的外部组件,内部用 {...rest} 透传 class 到\n真实 <div>)上。Svelte 的 CSS 静态分析只看本组件 markup,看不到 class\n跨组件透传,误判 selector 未使用(运行时实际生效)。\n\n按 Svelte 官方惯例改用 :global() 并锚定到本组件的 .island-anchor(原生\ndiv wrapper),既消除误报又不全局泄漏。功能完全不变。\n\n验证:pnpm check 0 errors/0 warnings(原 3 warnings 消除),build 通过。",
"is_bot": false,
"headline": "fix(island): 消除 3 个 css_unused_selector 误报",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T12:14:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "61fb0e74fdd727e97a84596d1c2dd5ba080f7273",
"body": "- vite.config.ts staged 钩子:locales glob 从 i18n:check 升级为\n i18n:check:strict,与 CI 门槛一致——本地提交 locale 改动时即检测\n untranslated 漂移,避免提交后才在 CI 挂。\n- 删除 scripts/i18n-fill.mjs + package.json 的 i18n:fill script:该脚本\n 被 i18n-translate.mjs 完全取代(translate 既保证完整键集又应用真实翻译,\n 而 fill 只会用 en 值占位,误跑会把已翻译覆盖回 en)。i18n:translate 是\n 唯一的 locale 生成入口。\n\n验证:i18n:check:strict 0 error/0 warning,pnpm check 0 errors,build 通过",
"is_bot": false,
"headline": "chore(i18n): staged 钩子升级 strict + 删除冗余 i18n-fill",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T12:07:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0575e355d23380103550a509548c5883fb340cda",
"body": "oxlint TS2305 根治:\n- vite.config.ts 的 PackPlugin 从 'vite-plus/pack'(4 层 export * 透传,\n oxlint type-check 穿不透)改为 'vite-plus'(re-exported Vite Plugin,是\n rolldown Plugin 的超类型)。\n- 顺带把三个插件的 apply: () => 'build' 简化为 apply: 'build'(字符串字面量\n 形式),符合 Vite Plugin 的 apply 类型(build|serve|predicate)。\n tsc --noEm\n[…]\n\nCI 收紧:\n- ci.yml: i18n:check → i18n:check:strict(翻译完整后 warning 也阻断,\n 防止退化;新增键必须翻译或加白名单才能合并)\n- package.json 加 i18n:translate script\n\n验证:i18n:check:strict 0 error/0 warning,pnpm check 0 errors,build 通过",
"is_bot": false,
"headline": "fix(i18n): 全量翻译 + oxlint 误报根治 + CI 收紧 strict",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T11:37:51Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e1c1215a8347eace03794803e69fb46d0f910cdf",
"body": "根 vite.config.ts 的 staged 块新增 `webui/src/locales/**` glob,\n触发 `pnpm --filter ./webui i18n:check`。\n\n注:此提交用 --no-verify 绕过 pre-commit。根 vite.config.ts:23 的\n`type Plugin as PackPlugin from 'vite-plus/pack'` 被 oxlint 的\ntype-aware 模式误报 TS2305(无法解析 export * 透传的 Plugin 类型),\n但 tsc --noEmit(CI 实际跑的)通过。这是 oxlint 类型解析的既有局限,\n非本次改动引入,后续 oxlint 升级或换用 tsc-based 检查可消除。",
"is_bot": false,
"headline": "chore(i18n): staged 钩子加 locales glob,提交 locale 文件时本地提示键对齐",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T08:31:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3e3f827035fef0e4226bba2be6b03a48318ee52c",
"body": "承接上一个 commit(拆分 + 检测脚本),本提交补齐遗漏的接线文件:\n- webui/src/lib/i18n.ts:2968 行原文件 → 19 行 re-export shim\n- webui/package.json:i18n:check / :check:strict / :fill script + tsx devDep\n- .github/workflows/ci.yml:i18n key-parity step\n- pnpm-lock.yaml:tsx 依赖锁定",
"is_bot": false,
"headline": "refactor(i18n): i18n.ts shim + package.json scripts + CI step + lockfile",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T08:12:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ffbd1e0c7de83ee804ef01484637bcc0c60a6df1",
"body": "- locale 从单文件 i18n.ts(2968 行,9 语言全量打进首包)拆到\n src/locales/{en,zh,es,fr,ar,ru,de,ja,ko}.ts + index.ts\n- 按需加载:en 同步作为 fallback(首屏安全),其余 locale 用 svelte-i18n\n register + 动态 import 各自独立 chunk(首包不再含全部语言)\n- 类型安全:en as const → Messages 类型(WidenLeaves 保留键结构,叶子放宽\n 到 string);每个 locale 用 const xx: Messages 强制\n[…]\n() 调用 + initI18n/setAppLocale\n 等导入路径零改动\n- tsx 声明为 webui devDep(脚本运行依赖)\n\n检测基线:0 error,1718 untranslated warning(回填 + 真实未翻译状态)\n\n注:vite.config.ts 的 staged 钩子因预存类型错误(vite-plus/pack 未导出\nPlugin)暂未提交,后续单独处理",
"is_bot": false,
"headline": "refactor(i18n): 按需加载 + 类型安全 + 键对齐检测 + CI",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T08:10:50Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4f6c1aa2fa61c535436bf8836a863522350366e9",
"body": "- EventCard 的 repo/folder/npm 打开按钮从 header 迁到 footer,左右\n cluster 用 justify-between 隔离对立(左侧主操作,右侧打开链接)\n- 新增 EventCardOpenActions 组件复用,TargetTarballDialog 接入同款\n 打开按钮 + tarball 默认展开 + max-h 自适应高度\n- EventDetailDialog: group trust 成员底部改三态按钮(关闭 / 放弃+保存)\n- 根因修复:模式切换+表单从「改即生效」重构为「本地暂存,Save 才提交」\n · deferS\n[…]\n 本地暂存\n · 模式切换本地化:不再每切换触发 setMemberInherit RPC,避免 daemon\n 回写覆盖 initialMode 快照导致脏检查失效,且消除 custom 编辑污染\n 继承视图的问题\n- 继承视图标签 Current → Inherit Values\n- i18n: 新增 discard/saveChanges/inheritValues 等 key",
"is_bot": false,
"headline": "feat(events): 打开按钮迁至 footer + trust 成员 Dialog 本地暂存编辑",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-08T06:43:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8cd0f29d6712d65ab9cb2f075de1fcbe342e9a81",
"body": null,
"is_bot": false,
"headline": "feat(tarball): pending 阶段预计算 tarball 预览 + 持久化(单包 & 递归)",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-07T19:12:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4ab5df9854108ab709af23f2dad764378aed515b",
"body": "reevaluateAutoClose() 同时被 blur/focus/pin 调用,而 blur 是 hide() 的必然\n副产物。原先写在该方法里的「有 activeEvents 且窗口隐藏 ⇒ show()」规则会在\n用户点 Hide window 时立刻把窗口拉回,并因 hide/show 抖动冻结在 0.1 enter seed。\n\n将该规则收敛到 store 的 \"event\" 订阅者 — 只有真正的新事件到达才有权复活\n隐藏窗口,reevaluateAutoClose() 回归 auto-close 资格评估的单一职责。\n\n补回归测试:hide() + blur 在 activeEvents 下保持 hidden。",
"is_bot": false,
"headline": "fix(tray): 有 activeEvents 时 hide() 被 blur 反弹 — 弹窗规则归位到 store 事件源",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-07T17:36:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "825b2b3b756b63304e77199fba69752250120bbf",
"body": null,
"is_bot": false,
"headline": "chore(pkg): opentray 系列跟进到 npm 0.11.2 — 修复 tray 挂载",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-07T15:21:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "781dc59e343ee016a4e86d39bf1f3fda902fc152",
"body": "pointer-events 改为由 phase 声明式驱动,设在 island-anchor(普通 DOM\ndiv,可用 style: 指令)而非 motion.div(组件,不支持 style: 指令)。\nhidden 态立即禁用交互(不等淡出动画完成),避免点击落在动画中的元素上。",
"is_bot": false,
"headline": "fix(island): hidden 态 pointer-events:none 设在 anchor 上",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-07T07:14:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5dec9841aef12c85a2f9f966f8ef6a76d64dbb2d",
"body": "覆盖分页、包名/关键词过滤、空组、orphan-pending sweep、\nJSON/boolean 序列化、corrupt payload 容错。全部通过。\n\n测试文件沿用现有 test/ 目录的 node:fs/os/path import 规范\n(与 avatar.test.ts 等一致)。",
"is_bot": false,
"headline": "test(db): event-db 分组历史查询单测(17 cases)",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-07T03:17:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dfb823eb6607be54ac389257b589160043b6198b",
"body": "event-db 新增按 groupId 聚合的历史查询,聚合在 DB 层完成:\n- HistoryEventGroupQuery/Result:分页 + 包名/关键词过滤\n- store/web-server 接线,orpc-contract/schemas 暴露契约\n- 前端 hasGroupEvents guard 过滤空组切片(防御 daemon 边界)",
"is_bot": false,
"headline": "feat(db): 服务端分组历史查询(grouped history pagination)",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-07T03:14:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dae505137947a28bb9fed844b400a786642d14db",
"body": "standalone pending 事件之前错误地显示 '0/1 resolved' 假进度条\n(单事件是 pending→done 二态,无子进度)。改为按 kind 生成有意义的\nsummary + detail text。group 事件保留真实 progress。",
"is_bot": false,
"headline": "feat(island): standalone 事件详情适配 — 动词+关键信息",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-06T17:21:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "025e132609ad8e6a7831844329aed50486aecc41",
"body": "- 引入 @humanspeak/svelte-motion,motion.div + animate 声明式驱动\n 单一可信源:phase(hidden/compact/expanded)→ TARGETS 外观对象\n 真实 spring 物理曲线,可中断、重复触发自然收敛\n- 三态状态机:hidden(不可见)↔ compact(药丸)↔ expanded(卡片)\n 新 expandable activity 默认展开,4s 自动收起到 compact(药丸常驻)\n- backdrop-filter 纳入 animate:compact blur(8px)↔ expanded blu\n[…]\nt.svelte:pending 事件用 groupEvents,summary 体现 kind\n (Trusted Publishing · N),detail 用 progress(resolved/total)\n- download-button 适配 showActivity(primaryAction=打开文件)\n- 灵动岛点击跳转 GroupEventCard + 布局稳定后平滑滚动",
"is_bot": false,
"headline": "feat(island): Dynamic Island 重构为 iOS 三态声明式动画",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-06T17:05:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "204f9f5ee5c7d0aa2e27af36619ff1771721c4b6",
"body": "opentray / @opentray/ext-webview 已发布到 npm(latest 0.11.0),不再\n需要 link:。同时它们带原生二进制(optionalDependencies 里按平台分发的\n.node),daemon 通过 index.ts 里的 dynamic `await import(\"opentray\")` 在\n运行时从 node_modules 解析(vite.config.ts 的 neverBundle 把它们保持为\nexternal),所以**必须在 dependencies**(host 安装 pnpm-pub 时才会拉取它\n们及其平台二进制),不\n[…]\nus 运行正常。\n\nNOTE: webui 构建因未提交的 motion-sv(webui/package.json 里的既有未提交\n改动)触发 motion-dom activeAnimations 缺失而失败——与本次 opentray 改动\n无关,是独立的 webui 依赖问题,需单独处理(pin motion-dom 或修 motion-sv\n版本)。本次用 --no-verify 提交。",
"is_bot": false,
"headline": "chore(pkg): opentray 系列跟进到 npm 0.11.0 + 移到 dependencies",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-06T16:12:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f9ebd934b930ebc7664353caa0f40ddcb1c291e4",
"body": "新增 src/daemon/db.ts:同步 Database/Statement 接口(shaped like\nbetter-sqlite3),+ openDatabase() 工厂按运行时选驱动:\n- Node → better-sqlite3(createRequire 加载,保持 external)\n- Bun → bun:sqlite(createRequire,运行时守卫,bundler 不静态解析)\n- Deno → @db/sqlite(jsr WASM,同步)\n\n三个驱动都是同步 API,所以 event-db/store/oRPC 全部保持原 sync 签名,\n零 \n[…]\nexisting,与本次改动无关;项目 tsc 干净)。\n\n验证:daemon tsc 0 错误;webui check 0 错误;event-db/store/orpc/\nproactive-events 共 92/92 通过;build 成功,better-sqlite3 仍 external、\nbun/deno 驱动以字符串守卫存在;node dist/cli.js status 运行正常。",
"is_bot": false,
"headline": "feat(db): 运行时可移植的 SQLite 抽象层(支持 Node/Bun/Deno)",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-06T11:48:37Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4ccad91e86a386b62f24c1cffa4e0f16e19b0597",
"body": null,
"is_bot": false,
"headline": "chore(pkg): safe-npm-sdk 改用 npm 发布版 ^0.4.0(不再 link)",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-06T06:17:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a9786bccfebaee08def94f96b0d8a7efda034072",
"body": "files: 新增 [\"dist\", \"README.md\"],确保发布只含产物 + 文档,不含源码/\n测试/spec。\n\n依赖整理(vp pack 把 dependencies 视为 external、devDependencies 视为\nbundle,已实测验证):\n- dependencies 只保留原生二进制依赖:better-sqlite3、@github/keytar。\n- 其余纯 JS 依赖(execa/otplib/ws/yargs/zod/@orpc/*/...)全部挪到\n devDependencies,由 vp pack bundle 进 dist,运行时不再从 nod\n[…]\n,其它依赖全部 bundle 进去。\n- npm pack --dry-run:tarball 只含 dist/ + README.md + package.json\n (106 文件,打包 1.5MB / 解压 4.0MB),无源码/测试泄漏。\n- node dist/cli.js status 正常运行,无模块解析错误。\n- daemon tsc 0 错误;webui check 0 错误。",
"is_bot": false,
"headline": "chore(pkg): 配置 files 字段 + 依赖整理(发包准备)",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-06T05:38:09Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "9b13940b2166ab255bb44c27dab713db28654de0",
"body": "1. GroupEventCard 日志显示所有成员的结果(而非仅 group.latest.result)。\n 折叠态:tally pill(成功/跳过/失败各一个小 chip,带状态色)+ 首个错误\n 首行预览。展开态:每个成员一块(包名 + 状态 pill 头部 + 10px 结果文本,\n 错误 destructive/90、其它 muted),柔和卡片分隔。\n\n2. ConfirmAll/RejectAll 进入 loading 并显示进度。batchRunning 在所有目标\n 成员异步 resolve 完成前保持 true(不再同步 try/finally 立即清零);\n 按钮显示 spinner + \"{done}/{total} resolved\"。批量目标 id 单独追踪,\n 进度准确反映 confirm/reject 的目标子集。\n\n验证:webui check 0 错误、build 成功;41/41 单测通过。",
"is_bot": false,
"headline": "feat(group): 多成员结果日志 + ConfirmAll loading/进度",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-06T05:15:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cfdb2f44a553182b0894da57a6a282268e2ac310",
"body": "批量 configure-trust 时,npm 的 POST 在包已有任一配置时返回 409\n(\"trusted publisher config already exists\"),无论 add 还是 update。旧实现\n凭前端 currentConfig 缓存决定 add/update,缓存为空就发 add → 已配置的包\n全失败。\n\n正交预检模型(webui 预显 + daemon 权威,两边都做):\n- 新增 config 相等比较 trustedPublisherConfigsEqual(webui + daemon 镜像),\n 忽略 registry id、归一化 Circle\n[…]\nkSkip / precheckConflict)。\naggregateGroupStatus 把 skipped 视为成功中性。\n\nspec/06.md 新增 6.2.7 节(含决策原话)。\n\n验证:webui check 0 错误、build 成功;daemon tsc 0 错误;\ntrusted-publishing-equality 8/8、store 31/31 等共 56/56 通过。",
"is_bot": false,
"headline": "feat(trust): batch OIDC skip/conflict 预检 + delete-then-put 自动解决",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-06T05:15:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4024f1b5fbfbf0f594a7ca1e18434679062cd655",
"body": "…m gate\n\n1. GroupEvent 日志显示:GroupEventCard 增加组级可展开日志区(复用\n EventCardBody 的折叠样式),resolved 后展示 group.latest.result 的\n 首行+全文。批量失败时错误信息直接显示在组卡片上,不再需要逐个点开\n 成员 Dialog。\n\n2. Retry/Reset 新 groupId:recreateMember/retryAll/resetAll 改为生成\n 新的 groupId(重试成员全部进新组),EventCard.retry() 同理(仅当\n 原事件有 groupId 时)。避免重试事件折回旧失败组导致的\"任务翻倍 +\n 残留错误任务\"。\n\n3. 继承成员的 confirm 门控:trustedPublishingReady 对 inherit 成员\n 改为认 group default 是否存在(而非成员自身 config),修复\"填了组\n 默认表单但成员确认按钮仍 disabled / ConfirmAll 后 config 为空\"的\n 问题。",
"is_bot": false,
"headline": "fix: group log visibility, retry groupId reuse, inherit-member confir…",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-05T17:45:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2720f2a472e6aaafb45b59129daeaa7c046bddc0",
"body": "## EventCard 三段式重构\n将单体 EventCard 拆分为 Header / Body / Footer 三个 shell-agnostic\n子组件,由 EventCard 装配器按 surface ('card' | 'dialog') 组合:\n- card 模式:包进 <Card> 三段(列表用)\n- dialog 模式:裸输出三段,由 EventDetailDialog 融合进 DialogHeader /\n 可滚动 body / footer 三行 grid——消除\"卡片套卡片\"的双层边框/padding\n\nEventDetailDialog 融合点:\n- 可见标题即 \n[…]\nentity+repositoryHint,断掉\n custom 成员编辑→回声→reset 循环\n\nspec/06.md 新增 6.2.5(只读展示三变体)+ 6.2.6(继承模型)两节,\n含决策原话。\n\n验证:daemon tsc 0 错误;pnpm check 0 错误;store.test.ts 31/31;\nbrowser trusted-publishing-dialog 测试通过。",
"is_bot": false,
"headline": "feat: EventCard 三段式重构 + Trusted Publishing 继承模型",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-05T16:54:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5fa0721444eaa5826206d9b4dd39d8cfedb2f97a",
"body": "…fixes\n\nDownloadButton: global component that triggers a download and listens for\nopentray's downloadcompleted event, then surfaces a Dynamic Island success\nnotification with an \"Open file\" action (daemon openExternal now expands ~\nto homedir so the action works). Island gains an optional action but\n[…]\nlocks private:true) — scope was a flawed heuristic that blocked\nlegitimate org-scoped packages. The disabled Publish button shows a tooltip\nwith the reason (pointer-events kept active so hover fires).",
"is_bot": false,
"headline": "feat: DownloadButton + Island actions, workspaces batch UX, settings …",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-05T07:35:16Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "32a797ab7ea78369b7d8172c73807521defcb261",
"body": "SettingsDialog: a global dialog (general / preferences / export) opened from\nthe main-shell toolbar. Built on the shadcn-svelte sidebar-13 block pattern\nwith a glass surface. General tab has theme (ButtonGroup) + language (Combobox);\npreferences is the single read/write source for the keep-open pin \n[…]\nts still have TS\nerrors on union-typed claims and are WIP.\n\nCommitted with --no-verify because the pre-commit hook fails on those\npre-existing trusted-publishing TS issues, not on SettingsDialog code.",
"is_bot": false,
"headline": "feat(settings): SettingsDialog (sidebar-13) + trusted-publishing WIP",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-05T03:47:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f35a0a22770b3dd0252ef7010b6a229c36564922",
"body": "Page reload drives visibilitychange->hidden while the document unloads,\nwhich the hide reporter mistook for a real window hide: it called\nwindowHidden(), and TrayHost.markHidden() poisoned visibility='hidden'.\nLater blurs short-circuit in reevaluateAutoClose (requires visibility\n'shown'), so the exi\n[…]\na show().\n\nArm an unload flag on pagehide/beforeunload (capture phase, before\nvisibilitychange) and skip the report when set. Real X-close/host hide\nare not page unloads, so their paths are unchanged.",
"is_bot": false,
"headline": "fix(tray): keep blur auto-close alive after page reload",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-04T14:40:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "405597b03ce321b7474eab8c5c7846947be8fe63",
"body": "Replace background-fill hover/active with backdrop-filter contrast so the\nnative blur reads through. Sidebar active uses contrast(2), hover contrast(1);\ntoolbar (pin/theme) reuses the same hover. Switch the Events nav icon to\nListTodo.",
"is_bot": false,
"headline": "style(ui): contrast-based hover/active for sidebar + toolbar",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-04T14:40:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "745d58c9ff98fa83d7944f6fe95669c727f20048",
"body": null,
"is_bot": false,
"headline": "fix(tray): align auto-close opacity timeline",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-04T12:41:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "aa014ced7f66063fdf34913bf2ab7c3791d522d1",
"body": null,
"is_bot": false,
"headline": "fix(dev): stabilize OpenTray WebUI startup",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-04T11:19:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f83398315afb98bace8bb8a335c9c06ee3c91157",
"body": "kezhaofeng's avatar was reachable but never cached: gravatar serves it as a\nJPEG, and fetchAndCacheAvatar only accepted PNG (isPngBuffer guard). So every\nfetch was rejected → null → a notfound.json negative-cache entry → the WebUI\nsaw a 404 and initials forever, even though the avatar genuinely exis\n[…]\n.png — the extension is just a stable URL; the\nserved type follows the actual cache).\n\nVerified: /api/avatar/kezhaofeng.png → 200 image/jpeg (128×128). Cleared the\nstale notfound.json so it re-caches.",
"is_bot": false,
"headline": "fix(avatar): accept JPEG/WebP/GIF avatars, not just PNG",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-04T07:07:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c18ecd584149c7d164ff9b241839b48c4d1e07e7",
"body": "… route\n\navatarUrlFor returned \"./api/avatar/...\". On nested routes like\n/profiles/<username> the relative \"./\" resolves against the current path,\nproducing /profiles/api/avatar/<user>.png → 404 even though the avatar is\ncached. Switched to an absolute \"/api/avatar/...\". The SPA has no base path, so\nthis resolves correctly everywhere.",
"is_bot": false,
"headline": "fix(avatar): use absolute path for avatar URL so it resolves from any…",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-04T06:58:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9a031c6caf21432f0571db008825fbec3c8bdaa1",
"body": "The daemon now owns avatar resolution/caching as the single source of truth,\nand the WebUI reads from it instead of each component independently hitting the\nnpm/gravatar network.\n\nBackend:\n - avatar.ts: new getCachedAvatarPath() entry point. Returns the on-disk PNG if\n hot, returns null on a rec\n[…]\nthat's the one legitimate anonymous lookup).\n\nVerified: /api/avatar/sindresorhus.png → 200 image/png (128×128) via the dev\nproxy; 404 for unresolved users; 401 without token. tsc + svelte-check clean.",
"is_bot": false,
"headline": "feat(avatar): unify avatar fetching — frontend reads from backend cache",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-04T06:51:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d95b0aa88302dd8f7875b8226d89eb76814bc673",
"body": "`safe-npm-sdk` now ships `lookupAvatar`, which is a faithful port of\nour own `lookupNpmProfileIdentity` (the SDK JSDoc says so). Drop the\nduplicated fallback chain (auth-profile email→Gravatar → registry\n`/-/user` → maintainer-search→Gravatar) and call the SDK instead,\nkeeping pnpm-pub's two layers \n[…]\n check's TS plugin reports a\npre-existing TS2591 false-positive (missing node:os/Buffer/process) on\navatar.test.ts — it reproduces on the pre-change file too; tsc and the\nreal test run are both clean.",
"is_bot": false,
"headline": "refactor(avatar): delegate resolution to safe-npm-sdk lookupAvatar",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-04T03:16:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8074487c499f1dc50e26a1a6d2a8e8f7e4e2f7f8",
"body": "addWorkspace() overwrote pinned and addedAt on an already-tracked\nworkspace. The WorkspaceDetail page's scan-on-mount $effect calls\nworkspace.scan -> addWorkspace({ pinned: false }), which silently reset\na user-set pin to false and re-broadcast the unpinned state — so opening\na workspace detail page\n[…]\nee call sites pass pinned:false). pinWorkspace and\nremoveWorkspace are unchanged.\n\nAdds a regression test covering both the in-memory and the\nreload-from-disk persistence of the pin through a re-scan.",
"is_bot": false,
"headline": "fix(store): preserve workspace pin/addedAt across re-scan",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-03T19:36:36Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "9bafe8c597acda07e2d147a6821d6ccfaa796f61",
"body": "Complete the TrayHost API that index.ts already referenced at HEAD:\nsetIcon() swaps the tray projection between the default mono template\nand the active color icon as pending-event state changes, and the menu\nnow relabels the primary item (Hide/Show window) to match real visibility\nand delegates a d\n[…]\n / Quit\n labels; drive iconProjection through trayHost.setIcon on pending changes.\n- tray-host.test.ts: cover setIcon no-op, Quit menu delegation, and the\n show/hide label sync; tighten mock typing.",
"is_bot": false,
"headline": "feat(tray): dynamic tray icon + show/hide/Quit menu wiring",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-03T19:35:25Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3b1f08dbfb1671ba4f442ef4190764b3c0a8f743",
"body": "Replaces the split REST + hand-rolled WebSocket protocol with one oRPC\nWebSocket mounted at /ws/rpc, carrying every WebUI action and the\nstate.subscribe projection stream. /api/* is now an explicit tombstone\nthat returns a 404 pointing at /ws/rpc.\n\n- Add the shared `webRpcContract` (Zod + oRPC) as t\n[…]\ngrate\n web-server-renew/ws-profile-authstatus/resolve-trust-auth/\n webui-protocol-types/publish-intercept coverage to oRPC.\n- Record milestones 228/229/230 in TASKS.md and archive the closed issues.",
"is_bot": false,
"headline": "refactor: migrate WebUI transport to a single /ws/rpc oRPC WebSocket",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-03T19:32:28Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b8d149c8fa7fc036199d205b2fdcfdb69cf2cc9f",
"body": "… all\n\nfetchAndCacheAvatar was called WITHOUT the profile's npm token at daemon\nstartup, so lookupNpmProfileIdentity skipped the authenticated-profile path\n(email → Gravatar) — the only path that reliably resolves an npm avatar today,\nand the one the WebUI's own profile.lookupNpm RPC uses. It instea\n[…]\n actually land (and cache) on first boot.\n\nThe fire-and-forget + negative-cache changes from the previous commit stand:\nstartup is still unblocked, and only deterministic not-found results are cached.",
"is_bot": false,
"headline": "fix(avatar): pass the profile token so the startup avatar resolves at…",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-03T18:27:44Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c5390fa8ffe26d03a22dee55d8a64189a671f154",
"body": "…esults\n\nThe daemon startup was slow and the avatar cache \"never hit\" for two compounding\nreasons, both in the avatar pre-fetch on the default profile:\n\n1. fetchAndCacheAvatar was awaited synchronously in bootDaemon, so the\n multi-second registry/gravatar probe blocked \"WebUI available\" (and the t\n[…]\ner URL is known up front. Removed leftover debug\nconsole.log breakpoints in bootDaemon.\n\nMeasured: failed-user lookup 2175ms → 0ms on next boot; dev startup ~15.5s →\n~5.3s with WS still returning 101.",
"is_bot": false,
"headline": "fix(daemon): avatar fetch no longer blocks startup + cache negative r…",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-03T18:16:51Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8b056e7a9b7cc32da147dfda95dde9166b720d1a",
"body": "The dev proxy was silently disabled, so every /ws/rpc upgrade fell through to\nSvelteKit (which neither upgrades nor rejects WS), and the connection hung —\nthe exact symptom reported.\n\nRoot cause: server.proxy was evaluated at config-load time via devDaemonProxy(),\nwhich reads PNPM_PUB_DEV_DAEMON_POR\n[…]\ngrade to /ws/rpc through the proxy returns\nHTTP 101 with a valid token (and 401 with a bad one), /__token proxies to the\ndaemon's response. Daemon-exit teardown still tears down the whole dev session.",
"is_bot": false,
"headline": "fix(dev): wire daemon proxy in configureServer so /ws/rpc doesn't hang",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-03T16:50:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ccbdbc7d2dac97fb1131fcf42b7b9fcfd96b1b06",
"body": "…rapper\n\nThe previous multi-PID supervisor-watch + ancestor-walk + SIGKILL exit-handler\nwas compensating for two things execa + a flat process chain make unnecessary.\n\nTwo realizations:\n\n1. execa already handles cleanup (the daemon dies when vite exits) and signal\n forwarding (SIGINT to vite reach\n[…]\nts pre-bloat state, and the dev script is one line.\n\nVerified both directions: kill daemon → dev session exits; SIGINT the top\nprocess → daemon + vite all gone, no survivors. tsc + svelte-check clean.",
"is_bot": false,
"headline": "refactor(dev): simplify daemon lifecycle with execa; drop pnpm-exec w…",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-03T16:15:01Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "cc53585481537f44c9138620196022eb54c8e650",
"body": "The daemon-dev Vite plugin now guarantees neither the daemon nor the UI can\noutlive the other, mirroring the old src/dev.ts supervisor contract.\n\nDaemon dies → dev session exits:\n The plugin's daemon `exit` handler calls shutdown(), which closes the Vite\n HTTP server and force-exits. Without the d\n[…]\n still works) and exits when ANY watched PID\n disappears, not just the one.\n\nVerified both directions: kill daemon → dev exits clean; SIGINT the pnpm\nwrapper → daemon + vite all gone, no survivors.",
"is_bot": false,
"headline": "fix(dev): daemon exit tears down the whole dev session, both directions",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-03T16:03:03Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "12c07df7a5f3289f775e9a91ab97dcc0224ad9cc",
"body": "….config.ts\n\nThree consolidations on top of the Vite+ migration, each eliminating a\nhand-rolled orchestration layer in favour of native Vite+ config blocks.\n\n1. Tests — merge 3 vitest configs into root vite.config.ts test.projects\n The standalone vitest.config.ts / vitest.browser.config.ts /\n vi\n[…]\nlp runs.\n\nAlso: .gitignore now ignores root .svelte-kit/ (a stray dev artifact).\n\nUnrelated concurrent edits left unstaged: src/shared/orpc-contract.ts,\nsrc/daemon/tray-host.ts, webui/src/lib/i18n.ts.",
"is_bot": false,
"headline": "refactor(toolchain): consolidate dev/build/test into vp + single vite…",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-03T13:20:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ab467c72b0bdf7e1e2d72bbe6fdb0e1c8c2ddc07",
"body": "This commit combines two streams of work onto a single fast-forward into main.\n\n1. Vite+ toolchain migration (vite-plus 0.2.1)\n - Bumped root vite ^5.4.21 -> ^8, vitest ^2.1.8 -> ^4.1 (installed: vite\n 8.1.0, vitest 4.1.9) to satisfy the migration baseline.\n - Ran `vp migrate --no-interactiv\n[…]\n run build: full pipeline green (webui + core + copy); bundled CLI runs.\n - Unit tests: 448/453 pass in-suite; the 5 \"failures\" are forks-worker\n timeouts under load and pass 15/15 in isolation.",
"is_bot": false,
"headline": "chore: merge Vite+ migration + in-flight feature work into main",
"author_name": "Gaubee",
"author_login": "Gaubee",
"committed_at": "2026-07-03T12:34:16Z",
"body_truncated": true,
"is_coding_agent": false
}
],
"releases_count": 7,
"commits_last_year": 199,
"latest_release_at": "2026-07-17T17:32:31Z",
"latest_release_tag": "v1.4.2",
"releases_from_tags": false,
"days_since_last_push": 4,
"active_weeks_last_year": 4,
"days_since_latest_release": 5,
"mean_days_between_releases": 1.2
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": false,
"has_contributing": true,
"health_percentage": 42,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "pnpm-pub",
"exists": true,
"license": "MIT",
"keywords": [
"2fa",
"daemon",
"npm",
"oidc",
"publish",
"totp",
"tray",
"trusted-publish"
],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/pnpm-pub",
"is_deprecated": false,
"latest_version": "1.4.2",
"repository_url": "https://github.com/Gaubee/pnpm-pub",
"versions_count": 13,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 2058,
"first_published_at": "2026-06-24T11:28:04.539000Z",
"latest_published_at": "2026-07-17T17:34:46.972000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
}
]
},
"popularity": {
"forks": 0,
"stars": 1,
"watchers": 0,
"fork_history": {
"days": [],
"complete": true,
"collected": 0,
"total_forks": 0
},
"star_history": null,
"open_issues_and_prs": 0
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [
"tsconfig.json",
"webui/tsconfig.json"
],
"toolchain_manifests": [],
"largest_source_bytes": 191430,
"source_files_sampled": 197,
"oversized_source_files": 3,
"agent_instruction_files": [
"AGENTS.md"
],
"agent_instruction_max_bytes": 5143
},
"dependencies": {
"manifests": [
"package.json",
"webui/package.json"
],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"npm"
],
"dependencies": [
{
"name": "@github/keytar",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "^7.0.0"
},
{
"name": "@opentray/ext-webview",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "^0.14.4"
},
{
"name": "opentray",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "^0.14.4"
},
{
"name": "validate-npm-package-name",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "^8.0.0"
},
{
"name": "@humanspeak/svelte-motion",
"manifest": "webui/package.json",
"ecosystem": "npm",
"version_constraint": "^0.7.17"
},
{
"name": "clsx",
"manifest": "webui/package.json",
"ecosystem": "npm",
"version_constraint": "^2.1.1"
},
{
"name": "geist",
"manifest": "webui/package.json",
"ecosystem": "npm",
"version_constraint": "^1.7.2"
},
{
"name": "highlight.js",
"manifest": "webui/package.json",
"ecosystem": "npm",
"version_constraint": "^11.11.1"
},
{
"name": "html5-qrcode",
"manifest": "webui/package.json",
"ecosystem": "npm",
"version_constraint": "^2.3.8"
},
{
"name": "marked",
"manifest": "webui/package.json",
"ecosystem": "npm",
"version_constraint": "^18.0.6"
},
{
"name": "mode-watcher",
"manifest": "webui/package.json",
"ecosystem": "npm",
"version_constraint": "^1.0.0"
},
{
"name": "svelte-i18n",
"manifest": "webui/package.json",
"ecosystem": "npm",
"version_constraint": "^4.0.1"
},
{
"name": "tailwind-merge",
"manifest": "webui/package.json",
"ecosystem": "npm",
"version_constraint": "^3.0.0"
},
{
"name": "zod",
"manifest": "webui/package.json",
"ecosystem": "npm",
"version_constraint": "^4.4.3"
}
],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 0,
"open_issues": 0,
"closed_ratio": null,
"closed_issues": 0,
"closed_unmerged_prs": 0
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "Gaubee",
"commits": 199,
"avatar_url": "https://avatars.githubusercontent.com/u/2151644?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"ci.yml",
"release.yml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"pnpm-lock.yaml"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": null,
"reason": "no pull request found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/30 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 3,
"reason": "project has 1 contributing companies or organizations -- score normalized to 3",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 0,
"reason": "project was created within the last 90 days. Please review its contents carefully",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": 10,
"reason": "packaging workflow detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "no SAST tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 0,
"reason": "13 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "43c3805cd20c97394b171201cb05f9b44cd60c1a",
"ran_at": "2026-07-23T00:53:51Z",
"aggregate_score": 2.7,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-18T06:58:31Z",
"oldest_open_prs": [],
"last_merged_pr_at": null,
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/Gaubee/pnpm-pub",
"host": "github.com",
"name": "pnpm-pub",
"owner": "Gaubee"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"security": 27,
"vitality": 74,
"community": 39,
"governance": 40,
"engineering": 62
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 74,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "moderate",
"name": "Development activity",
"note": null,
"notes": [],
"value": 57,
"inputs": {
"commits_last_year": 199,
"human_commit_share": 1,
"days_since_last_push": 4,
"active_weeks_last_year": 4
},
"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": "4/52 weeks with commits",
"points": 2.8,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 4
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "199 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 199
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 100,
"inputs": {
"releases_count": 7,
"latest_release_tag": "v1.4.2",
"releases_from_tags": false,
"days_since_latest_release": 5,
"mean_days_between_releases": 1.2
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "7 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 7
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 5 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 5
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~1.2 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 1.2
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "unverified",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": "repository_too_young",
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": null,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "maintenance record not established from the collected data",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_unverified",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "at_risk",
"name": "Community & Adoption",
"value": 39,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 0,
"stars": 1,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "1 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 1
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "0 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 0
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "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": 55,
"inputs": {
"packages": [
"pnpm-pub"
],
"dependents": null,
"ecosystems": "npm",
"total_downloads": null,
"monthly_downloads": 2058
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "2,058 downloads/month across npm",
"points": 44.2,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 2058,
"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": "at_risk",
"name": "Sustainability & Governance",
"value": 40,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 13,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 1,
"top_contributor_share": 1
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 100% of commits",
"points": 0,
"status": "missed",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "1 contributors",
"points": 1.4,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 1
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 3,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "critical",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): Issue resolution, PR acceptance. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"issue_resolution",
"pr_acceptance"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 1,
"inputs": {
"merged_prs": 0,
"open_issues": 0,
"closed_issues": 0,
"issue_closed_ratio": null,
"closed_unmerged_prs": 0
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "no issues or no data",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_issues_or_data",
"params": {}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "no decided pull requests or no data",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_decided_prs_or_data",
"params": {}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"verified_domain"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 62,
"inputs": {
"followers": 100,
"owner_type": "User",
"is_verified": null,
"owner_login": "Gaubee",
"public_repos": 199,
"account_age_days": 5090
},
"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": "100 followers of Gaubee",
"points": 14.4,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 100,
"login": "Gaubee"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "199 public repos, account ~13 yr old",
"points": 25,
"status": "met",
"details": [
{
"code": "public_repos",
"params": {
"count": 199
}
},
{
"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": [
"pnpm-pub"
],
"ecosystems": "npm",
"any_deprecated": false,
"min_days_since_publish": 5
},
"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 5 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 5
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "13 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 13
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "moderate",
"name": "Engineering Quality",
"value": 62,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_ci_tests"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 60,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "2 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 2
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 65,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": null,
"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": null,
"points": 0,
"status": "missed",
"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": "critical",
"name": "Security",
"value": 27,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "critical",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): CI-Tests, Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"ci_tests",
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 27,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 16,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 2,
"scorecard_aggregate": 2.7
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 0.8,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "no SAST tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "13 existing vulnerabilities detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 2
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "moderate",
"name": "AI Readiness",
"value": 68,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "excellent",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 1,
"agent_instruction_files": [
"AGENTS.md"
],
"agent_instruction_max_bytes": 5143
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "AGENTS.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "AGENTS.md"
}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "100 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 100,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "at_risk",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 43,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"pnpm-lock.yaml"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [
"tsconfig.json",
"webui/tsconfig.json"
],
"agent_commit_share": 0,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "tsconfig.json, webui/tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "tsconfig.json, webui/tsconfig.json"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 100",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "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": 99,
"inputs": {
"primary_language": "TypeScript",
"largest_source_bytes": 191430,
"source_files_sampled": 197,
"oversized_source_files": 3
},
"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": "3/197 source files over 60KB",
"points": 54.2,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 197,
"oversized": 3
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"deps.dev does not index npm:pnpm-pub@1.4.2; advisories assessed against the repository dependency graph instead"
],
"report_type": "repository",
"generated_at": "2026-07-23T00:53:56.349611Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/g/Gaubee/pnpm-pub.svg",
"full_name": "Gaubee/pnpm-pub",
"license_state": "standard",
"license_spdx": "MIT"
}