Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 1.13.0 · 2026-07-23 11:42 UTC

modelzen / feishu-codex-bridge

把 codex/claude 接入飞书

TypeScriptMIT★ 41 estrellas⑂ 12 forksdesde may 2026Ver en GitHub ↗

modelzen/feishu-codex-bridge tiene un índice de salud de 51 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Vitality (76/100) y la más baja, Security (18/100). Se actualizó por última vez hace 2 días. Una sola persona concentra la mayor parte del trabajo reciente.

51
global / 100
Moderado

Índice de salud del software

Las métricas se agrupan en categorías ponderadas sobre una escala de 1 a 100. El resultado global parte de su media; cuando la evidencia pública activa la Política de Jurisdicciones de Alto Riesgo, la calificación se ajusta y recibe el límite 49 (En riesgo). Preparación para IA queda fuera.

51
Excelente85-100Ejemplar; cumple prácticamente todos los criterios evaluados
Bueno70-84Saludable; carencias menores
Moderado50-69Aceptable con carencias notables; se recomienda revisión
En riesgo30-49Debilidades significativas; su adopción exige cautela
Crítico1-29Problemas graves (proyecto abandonado, un solo mantenedor, sin higiene)
VitalidadComunidad yAdopciónSostenibilidady GobernanzaCalidad deIngenieríaSeguridadPreparaciónpara IA

Perfil de puntuación

Cada eje es una categoría. La forma importa más que la media: un proyecto sano llena toda la figura, mientras que un perfil de picos y cráteres indica que la fortaleza en una dimensión enmascara el riesgo en otra.

Titularidad

modelzenOrganización
1 seguidor3 repositorios públicosdesde abr 2026

Este repositorio está respaldado por una organización: una custodia compartida y responsable que puede sobrevivir a cualquier mantenedor individual.

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicaciónEtiquetas
npm@modelzen/feishu-codex-bridge0.6.10241952hace 5 díasfeishularkcodexapp-serverclibridgebot

Métricas por categoría

Vitalidad

¿Está vivo el proyecto: se escribe código y se publican versiones?

76Bueno · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 2 días
5.5/36Cadencia de commits — 8/52 semanas con commits
18/18Volumen de commits — 263 commits en el último año
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Datos de entrada utilizados
commits_last_year263
human_commit_share1
days_since_last_push2
active_weeks_last_year8
Cómo se puntúa
27/27Publica versiones — 37 versiones publicadas
36/36Recencia de las versiones — última versión hace 5 días
27/27Cadencia de publicación — una versión cada ~3,1 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count37
latest_release_tagv0.6.10
releases_from_tagsno
days_since_latest_release5
mean_days_between_releases3,1
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Signed-Releases. Los pesos restantes se han renormalizado.

Comunidad y Adopción

¿Tiene el proyecto usuarios, descargas, atención y unas condiciones acogedoras para quienes contribuyen?

46En riesgo · 18% del índice global
Cómo se puntúa
26/60Estrellas — 41 estrellas
8.7/25Forks — 12 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks12
stars41
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (MIT)
0/18Guía CONTRIBUTING
0/13.5Código de conducta
0/7.2Plantilla de issues
0/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno
Cómo se puntúa
45.1/80Descargas mensuales — 2419 descargas/mes en npm
0/20Dependientes en el registro — no lo informa este ecosistema
Datos de entrada utilizados
packages@modelzen/feishu-codex-bridge
dependents
ecosystemsnpm
total_downloads
monthly_downloads2419
Excluidos de la puntuación (sin datos o no aplicable): Dependientes en el registro. Los pesos restantes se han renormalizado.

Sostenibilidad y Gobernanza

¿Sobrevivirá el proyecto a sus personas: factor bus, capacidad de respuesta, quién lo respalda y mantenimiento del paquete?

48En riesgo · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
0.5/22.5Distribución de commits — el principal contribuyente firma el 98% de los commits
4.1/13.5Amplitud de contribuyentes — 3 contribuyentes
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Datos de entrada utilizados
bus_factor1
contributors_sampled3
top_contributor_share0,978
Cómo se puntúa
15.6/46.8Resolución de issues — 33% de issues cerradas
38.2/38.3Aceptación de PR — 2/2 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs2
open_issues2
closed_issues1
issue_closed_ratio0,333
closed_unmerged_prs0
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
2.2/25Alcance del propietario — 1 seguidores de modelzen
4.9/25Trayectoria — 3 repos públicos, cuenta de ~0 años
Datos de entrada utilizados
followers1
owner_typeOrganization
is_verified
owner_loginmodelzen
public_repos3
account_age_days97
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en npm
35/35Recencia de publicación — última publicación hace 5 días
20/20Historial de versiones — 52 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packages@modelzen/feishu-codex-bridge
ecosystemsnpm
any_deprecatedno
min_days_since_publish5

Calidad de Ingeniería

¿Existen unas prácticas mínimas de ingeniería y documentación?

58Moderado · 20% del índice global
Cómo se puntúa
0/24Flujos de trabajo de CI
24/24Pruebas presentes
0/16Configuración de linter
0/9.6Hooks de pre-commit
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — sin datos
Datos de entrada utilizados
has_cino
has_tests
has_editorconfigno
has_linter_configno
has_precommit_configno
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: CI-Tests. Los pesos restantes se han renormalizado.

Documentación

100Excelente
Cómo se puntúa
30/30README
25/25Directorio de documentación
15/15Sitio de documentación / página del proyecto — https://bridge.vonvon.cc
10/10Descripción del repositorio
10/10Topics — 4 topics
10/10Wiki
Datos de entrada utilizados
topicsclaude-code, codex, feishu, lark
has_wiki
homepagehttps://bridge.vonvon.cc
has_readme
has_docs_dir
has_description

Seguridad

¿Son sólidas las prácticas visibles de seguridad y de cadena de suministro, sin exposición jurisdiccional de alto riesgo sin resolver?

18Crítico · 16% del índice global
Cómo se puntúa
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — sin datos
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
0/10Dangerous-Workflow — sin datos
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Licencia — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — sin datos
2.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 5
0/5SAST — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — sin datos
0/7.5Token-Permissions — sin datos
0/7.5Vulnerabilities — 43 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated13
scorecard_versionv5.5.0
checks_inconclusive5
scorecard_aggregate1,8
Excluidos de la puntuación (sin datos o no aplicable): ci_tests, dangerous_workflow, packaging, signed_releases, token_permissions. Los pesos restantes se han renormalizado.

Preparación para IA

¿Hasta qué punto está el repositorio preparado para desarrollarse y mantenerse con agentes de codificación de IA? Es una insignia independiente y experimental — peso 0,0, de modo que se presenta por separado y no afecta a la puntuación de salud global.

59Moderado · 0% del índice global
Cómo se puntúa
0/45Instrucciones para agentes — sin CLAUDE.md / AGENTS.md / reglas de editor
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 99 de 100 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,99
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
0/11Configuración de lint / formato
11/11Verificación estática de tipos — tsconfig.json
10/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 70 de los últimos 100 commits con autoría o crédito de agente
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
5/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 5
Datos de entrada utilizados
has_nixno
has_tests
lockfilespackage-lock.json
has_dockerfileno
typed_language
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configstsconfig.json
agent_commit_share0,7
toolchain_manifests
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — TypeScript (tipado estático)
54/55Tamaños de archivo manejables — 4/210 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageTypeScript
largest_source_bytes263.786
source_files_sampled210
oversized_source_files4

Datos clave

41estrellas de GitHub
3contribuidores
263commits en los últimos 12 meses
2días desde el último push
37versiones publicadas
1factor bus
2issues abiertas
npmecosistemas de paquetes

Advertencias de recopilación de datos

  • 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:@modelzen/feishu-codex-bridge@0.6.10; advisories assessed against the repository dependency graph instead

Más detalle

Historial de estrellas y forks 0 ★ / 12 ⇿
0Estrellas
12Forks
29Versiones

Cuándo se añadió cada estrella y fork, recopilado de GitHub y agrupado por día. El crecimiento acumulado se sitúa justo encima de las adiciones diarias que lo componen, de modo que ambos se leen en conjunto: la acumulación orgánica sostenida no se parece en nada a un pico abrupto y efímero. Cuando esa diferencia es medible, se informa como autenticidad del crecimiento.

0246810121222026-062026-062026-07
Mayor 0Menor 4Parche 25
OpenSSF Scorecard 1.8 / 10
1.8agregado

Evaluación de seguridad independiente y agnóstica en cuanto a herramientas, procedente del proyecto de código abierto OpenSSF Scorecard. Cada comprobación premia una práctica de seguridad, no la herramienta de un proveedor concreto. Las comprobaciones que Scorecard no pudo determinar se marcan como n/d y se excluyen de la puntuación de seguridad (nunca se cuentan como cero).Scorecard v5.5.0 · 2026-07-23 11:42 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
n/dCI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
n/dDangerous-Workflowno workflows found
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
n/dPackagingpackaging workflow not detected
5Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 5
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
n/dToken-PermissionsNo tokens found
0Vulnerabilities43 existing vulnerabilities detected
Dependencias directas 4
RegistroPaqueteRestricción de versiónManifiesto
npm@larksuiteoapi/node-sdk^1.65.0package.json
npmcommander^12.1.0package.json
npmcross-spawn^7.0.6package.json
npmqrcode-terminal^0.12.0package.json
Todas las dependencias no recopilado

No fue posible recopilar el conjunto de dependencias resuelto para este informe: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [
        "claude-code",
        "codex",
        "feishu",
        "lark"
      ],
      "is_fork": false,
      "size_kb": 10628,
      "has_wiki": true,
      "homepage": "https://bridge.vonvon.cc",
      "languages": {
        "Shell": 5299,
        "JavaScript": 7145,
        "TypeScript": 2617851
      },
      "pushed_at": "2026-07-21T02:18:29Z",
      "created_at": "2026-05-29T07:31:08Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-22T22:08:55Z",
      "description": "把 codex/claude 接入飞书",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "Organization",
      "login": "modelzen",
      "company": null,
      "location": null,
      "followers": 1,
      "avatar_url": "https://avatars.githubusercontent.com/u/276898184?v=4",
      "created_at": "2026-04-17T07:28:12Z",
      "is_verified": null,
      "public_repos": 3,
      "account_age_days": 97
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.6.10",
          "kind": "patch",
          "published_at": "2026-07-18T02:54:42Z"
        },
        {
          "tag": "v0.6.9",
          "kind": "patch",
          "published_at": "2026-07-10T09:23:35Z"
        },
        {
          "tag": "v0.6.8",
          "kind": "patch",
          "published_at": "2026-07-09T13:53:31Z"
        },
        {
          "tag": "v0.6.7",
          "kind": "patch",
          "published_at": "2026-07-09T13:25:40Z"
        },
        {
          "tag": "v0.6.6",
          "kind": "patch",
          "published_at": "2026-07-08T13:09:12Z"
        },
        {
          "tag": "v0.6.5",
          "kind": "patch",
          "published_at": "2026-07-03T16:51:24Z"
        },
        {
          "tag": "v0.6.4",
          "kind": "patch",
          "published_at": "2026-06-30T10:30:44Z"
        },
        {
          "tag": "v0.6.3",
          "kind": "patch",
          "published_at": "2026-06-29T12:42:55Z"
        },
        {
          "tag": "v0.6.2",
          "kind": "patch",
          "published_at": "2026-06-22T10:23:33Z"
        },
        {
          "tag": "v0.6.1",
          "kind": "patch",
          "published_at": "2026-06-20T02:22:06Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-06-18T17:10:30Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-06-17T14:37:04Z"
        },
        {
          "tag": "v0.4.3",
          "kind": "patch",
          "published_at": "2026-06-16T16:25:25Z"
        },
        {
          "tag": "v0.4.2",
          "kind": "patch",
          "published_at": "2026-06-15T16:33:50Z"
        },
        {
          "tag": "v0.4.1",
          "kind": "patch",
          "published_at": "2026-06-15T12:35:18Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-06-14T15:51:21Z"
        },
        {
          "tag": "v0.3.11",
          "kind": "patch",
          "published_at": "2026-06-12T11:04:58Z"
        },
        {
          "tag": "v0.3.10",
          "kind": "patch",
          "published_at": "2026-06-11T15:14:36Z"
        },
        {
          "tag": "v0.3.9",
          "kind": "patch",
          "published_at": "2026-06-10T16:46:08Z"
        },
        {
          "tag": "v0.3.8",
          "kind": "patch",
          "published_at": "2026-06-10T14:41:25Z"
        },
        {
          "tag": "v0.3.7",
          "kind": "patch",
          "published_at": "2026-06-09T13:28:43Z"
        },
        {
          "tag": "v0.3.6",
          "kind": "patch",
          "published_at": "2026-06-09T04:02:10Z"
        },
        {
          "tag": "v0.3.5",
          "kind": "patch",
          "published_at": "2026-06-08T12:46:02Z"
        },
        {
          "tag": "v0.3.4",
          "kind": "patch",
          "published_at": "2026-06-07T14:29:25Z"
        },
        {
          "tag": "v0.3.3",
          "kind": "patch",
          "published_at": "2026-06-05T10:50:29Z"
        },
        {
          "tag": "v0.3.2",
          "kind": "patch",
          "published_at": "2026-06-05T05:38:51Z"
        },
        {
          "tag": "v0.3.1",
          "kind": "patch",
          "published_at": "2026-06-05T03:26:17Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-06-04T15:28:13Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-06-04T00:57:32Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-06-02T12:35:35Z"
        },
        {
          "tag": "v0.1.8",
          "kind": "patch",
          "published_at": "2026-06-01T12:04:30Z"
        },
        {
          "tag": "v0.1.7",
          "kind": "patch",
          "published_at": "2026-06-01T10:31:46Z"
        },
        {
          "tag": "v0.1.6",
          "kind": "patch",
          "published_at": "2026-06-01T09:03:01Z"
        },
        {
          "tag": "v0.1.5",
          "kind": "patch",
          "published_at": "2026-06-01T08:34:54Z"
        },
        {
          "tag": "v0.1.4",
          "kind": "patch",
          "published_at": "2026-06-01T08:12:59Z"
        },
        {
          "tag": "v0.1.3",
          "kind": "patch",
          "published_at": "2026-06-01T07:45:22Z"
        },
        {
          "tag": "v0.1.2",
          "kind": "patch",
          "published_at": "2026-05-30T15:27:18Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "fe0f67d526b538afa26b0cb159d55e063f8cc28f",
          "body": null,
          "is_bot": false,
          "headline": "fix: remove manual bot registration",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-18T04:29:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "52e8a4234d43c2338c3e191f6b1ce9a09b5e48dc",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.6.10",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-18T02:54:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2fe63250a0de8816ee8f51d8be2d259232391477",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'codex/session-resume-titles'",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-17T03:12:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e70961a0870936fdb35d3f313ebe5e77885f2478",
          "body": null,
          "is_bot": false,
          "headline": "docs: 添加功能演示动图",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-17T03:12:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2268259848ef6b54adbd58939fd3c8d3df834980",
          "body": null,
          "is_bot": false,
          "headline": "fix(settings): 精简会话标题策略摘要",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-17T03:07:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ae7ef60265aad28c7c11ddd6c01ec81a228bc1c",
          "body": null,
          "is_bot": false,
          "headline": "fix(session): 完善 resume 标题与专项设置体验",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-17T02:29:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "30d5b9d8ac4d55eb144877fad88e3de5bc76eeab",
          "body": null,
          "is_bot": false,
          "headline": "feat(session): 为 Bridge 会话生成原生 resume 标题",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-16T10:02:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "24d1c65f348095492c0a3277a157ba24719df92b",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.6.9",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-10T09:23:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ecafd7202ed8260f08a47c46c5cf9604eeafc6f",
          "body": null,
          "is_bot": false,
          "headline": "merge: 普通任务完成提醒策略",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-10T09:11:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6b2342c89df5227b1f53ae45715e56c35416430e",
          "body": null,
          "is_bot": false,
          "headline": "feat(reminder): 增加普通任务完成提醒策略",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-10T09:10:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eda0c545cde2d9ffe270ae90ce3dbfe6f02d1752",
          "body": null,
          "is_bot": false,
          "headline": "feat(project): 支持配置空白项目默认目录",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-10T02:34:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "040a76925cc40635990398f43f07e069f1b37a22",
          "body": null,
          "is_bot": false,
          "headline": "fix(model): 支持 max 和 ultra 推理强度",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-10T02:21:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b523536ef58ed1d983e645a98e0140c536c35227",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.6.8",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T13:53:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e7700b327930dc3985e6707cc173ba7c4c65de1d",
          "body": "- toUserMessage 把 input.images 编成 image content block(claude 群此前收不到图,codex 群能收到)\n- magic bytes 嗅探判 media_type,修掉扩展名误标(无 content-type 的 JPEG 被存成 .png)被 API 拒\n- 审计确认其余入站类型(文件/引用/上文/身份/卡片正文/合并转发/其它媒体)两后端已等价;\n  文件读权限上 claude 反而更宽(各档都能读 inboundDir,codex 仅 full)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(claude): 入站图片 base64 喂给 SDK,与 codex localImage 对齐",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T13:31:10Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b9efcf116493ae78c9a3085c162ce949b6ecb69d",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.6.7",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T13:25:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ceef637452d7acdf74dca77583583fe03c8bb7d",
          "body": "- 私聊菜单「🔄 重连」→「🔁 重启」:旧重连按钮只读展示状态、无副作用,真断线时重启\n  才有效。两步确认(仿删除项目)走稳定的树外重启;前台 run 场景不做无效 restart;\n  保留旧重连卡/action 兼容聊天记录里的旧卡\n- 更新加跨进程互斥锁(acquireUpdateLock,O_EXCL + 陈旧回收/属主校验):Web「升级」与\n  私聊「更新」共用,挡住并发 npm i -g 装坏全局目录;拿不到锁提示「进行中」不叠跑\n- 网页升级失败不再静默:detached helper 把进度/结果写 update-status.json,新增\n  GET /api/update/status,前端点「升级」后轮询——失败明确报错、按钮 in-flight 禁用防\n  重复点击(成功仍由版本变更流翻「已是最新版」)\n\ntest:新增 test/update-lock.test.ts(锁互斥/陈旧回收/属主校验 + 状态读写)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(console): 私聊「重连」改「重启」+ 更新并发锁 + 网页升级失败反馈",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T12:36:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a13a622a1b95c493314d58c087c4ce379ae45d16",
          "body": "已在跑时再执行 start / 点网页「启动」,旧的无条件 startNow 会起一个抢锁必败的重复\n实例;它退出时 eager 写的 pid + clearServicePid 把在跑者的 service.pid 抹掉,导致\nisServiceRunning()=false、更新/重启按钮此后静默 no-op——与「更新了没重启」同症状且\n不自愈。\n\n- installWinStartup:仅在没有在跑实例时 startNow(Windows 无 launchd/systemd 那样的\n  bootout,install 不能等价重启,已在跑就只刷新自启文件)\n- startNow:eage\n[…]\nservice.pid 前先看有没有活属主,有则跳过——让抢锁赢家的\n  recordServicePid 成为唯一真值来源,顺带收敛双 relauncher 并发竞态(树外 relauncher\n  路径旧 daemon 已强杀=死,仍照常立即写,行为不变)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(win): install/startNow 不覆盖在跑 daemon 的 service.pid",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T12:36:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1aedd669178af0bcc6b9670f5d82d36e17947ead",
          "body": "- relaunched 日志读回 startNow 写到正确 appDir 的 service.pid,打印新 daemon\n  真实 pid(之前只有临时 relauncher 的 self pid,看起来和控制台对不上)。\n- PS 脚本开头 $ProgressPreference='SilentlyContinue',去掉 stderr 被序列化成的\n  #< CLIXML 进度噪音。\n- 注释标注:同步 spawnSync 执行 PowerShell 是修复本身(detached fire-and-forget\n  会在 WMI 创建完成前被回收,relauncher 根本起不来),别改回 detached。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "polish(win): relaunch 日志打印新 daemon pid + 抑制 PowerShell CLIXML 噪音",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T11:29:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "362e5b7cc2648df6ba6c7e263369865715ddb8e4",
          "body": "网页控制台开着时,每 5s 一次的 /api/daemon 轮询会走 statusWinStartup →\nisInstalled() 的 `reg query`,而它没带 windowsHide:无窗口的隐藏 daemon 每次\nspawn 一个控制台程序又不隐藏,就弹一个黑窗 → 5s 一闪。给三处 reg(query/add/\ndelete)都补 windowsHide:true。顺带修 open-url 的 `cmd /c start`(开浏览器时也会\n一闪,虽非周期性),browser 是独立进程、隐藏 cmd 不影响它启动。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(win): 给 Windows 裸 spawn 补 windowsHide,消除黑窗每 5s 闪烁",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T11:21:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "85fa81f5e669cc21b3ecb1774105b9a40aa389a6",
          "body": "-EncodedCommand 未解决 relauncher 不启动的问题(真机:submitted 有、relauncher\n从不 start、pid 不变),说明卡点不是引号而是 WMI 提交本身,但旧代码 fire-and-\nforget 派生 PowerShell、丢弃其输出,失败完全不可见。\n\n改为同步 spawnSync 执行 PowerShell(WMI create 只是发起、<1s 返回,短暂阻塞可接受),\n并把它的 stdout/stderr/退出码写进 service.err.log。PowerShell 脚本每个分支都输出\n结果串:成功 `cim rv=0 pid=N`\n[…]\nasks 并输出\n`schtasks create=.. run=..`。只有确认到 launch(cim rv=0 或 schtasks run=0)才算\n成功,否则回退 node 端 schtasks。下次点重启,日志即可定位 WMI 到底成没成、报什么。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(win): 同步执行 PowerShell 并捕获 WMI 返回,让提交失败可见",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T11:17:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5f4e89ff3d5edd21cd12e5c6a656a0cdefa0ec06",
          "body": "上一版 relauncher 依赖它自己进程的环境去推算 ~/.feishu-codex-bridge 目录,\n但它是被 WMI/计划任务拉起的——那套机制未必把当前用户的 USERPROFILE/PATH 传给\n子进程。在环境被剥离/替换的机器上会两种失败:\n1) relauncher 用错的 appDir 找不到 relaunch 请求 → 又白跑一次;\n2) 就算找到,它拉起的新 daemon 也继承错环境 → 新 daemon 去错目录找 bots.json\n   → 连不上。本机 WMI 恰好保留了用户环境所以能过,别人的机器不一定。\n\n改成 relauncher 完全不依赖自身环境\n[…]\nviceErr 支持指定输出文件(relauncher 写到真实 appDir 的 service.err.log)。\n\n新增单测覆盖:请求路径带空格/单引号仍正确、appDir 由请求路径 dirname 推导、\nUSERPROFILE 透传到 start。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(win): relauncher 完全脱离自身环境,跨机器可靠(传请求路径 + 携带 USERPROFILE)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T11:08:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0f04223b9ceaabf90266ab115a31cc55b2f7cc5b",
          "body": "真机验证暴露:restartWinStartup 提交了 relauncher(日志有 \"submitted async\nrelaunch\"),但 __win-relaunch 进程从没跑起来(relaunch.json 一直没被认领、\npid 不变)。手动 `feishu-codex-bridge __win-relaunch` 却完美工作(start→\ntaskkill→relaunched,pid 正常更换)——证明 relauncher 本体正确,坏的只是「经\nPowerShell 投递」这一步。\n\n根因:PS 脚本作为 -Command 的单个字符串参数,穿过 Node spawn \n[…]\nEncodedCommand(base64/UTF-16LE)投递:spawn 参数是纯 ASCII\n的 base64,无引号/空格可被搅乱,PowerShell 解码后拿到逐字节一致的脚本。新增\nencodePowershellCommand + 往返单测。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(win): relauncher 改用 -EncodedCommand 投递,修 WMI 从不启动",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T10:56:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7bca8b20a809bf4507c537ff70d9514478ae4b48",
          "body": "Windows 上点更新按钮「版本更新了但新服务没拉起」的根因:restartWinStartup\n把 killService(taskkill /pid <service.pid> /T /F) 和 startNow() 放在同一进程\n顺序执行,而这个进程恒在被 /T 杀的树里——DM 卡片路径就是 daemon 自己(自杀),\nWeb 路径是 daemon 的 detached 子 helper(detached 不改 ParentProcessId,被 /T\n连带杀)。于是 startNow 永远够不着,新服务起不来(Windows 无崩溃自拉起)。\nmacOS/Linux 靠 laun\n[…]\n.log,内置 logs 命令即可看到更新/重启轨迹。\n\nmacOS/Linux 路径未改动。新增 test/win-relaunch.test.ts 覆盖 WMI 命令构造与\n引号转义、relaunch 顺序、旧不死不起新、并发认领单赢、无请求 no-op。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(win): 更新后经「树外 relauncher」重启,不再自杀式杀掉起新服务的进程",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T08:34:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2499db6b855c33387b70abba32d96d15648f2034",
          "body": "总览页 5s 轮询会整页重渲,原先每次重渲都新建 updateBody(文案「版本\n检查中…」)并立刻打 /api/update/check——该接口在服务端 spawn `npm view`\n(最长 20s)。结果:控制台一开着就每 5 秒查一次 npm registry + 界面持续\n闪「版本检查中…」,用户反馈了这个现象。\n\n改为结果缓存驱动:\n- lastUpdate 缓存检查结果,重渲直接渲缓存,只在首次/过期时真查;\n- 运行版本变化时(更新+重启完成)作废缓存并当场补查,保住点更新后\n  ≤5s 看到「已是最新版」的反馈,且消除 loadState/loadDaemon 同周期竞\n[…]\n个 npm view;\n- 软失败(registry 不可达,服务端仍回 200 + latest:null)只缓存 ~2min\n  便自动复查,不把「查询失败」钉住 30min。\n\n效果:从「开页就永久每 5s 查」降到「开页查一次,之后按需/30min」。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(web): 版本检查改缓存驱动,不再每 5s spawn npm view",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-09T06:51:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "845d1d3c314a3e3c5c702108340f77e514dd0136",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.6.6",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-08T13:08:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d627ecd8cf8050b0c803ac9919fcbbde15256b2e",
          "body": "单会话群此前只能 /compact 压缩,无法清空上下文或切回历史会话。补齐 Codex 式闭环:\n\n- /clear:停泊当前会话 + 重绑到全新后端 thread(保留 model/effort/backend,旧 thread\n  留档可 /resume),事后卡片讲清「飞书聊天记录不受影响」。同步预留会话防竞态。\n- /resume:复用历史选择卡(文案改「就地切回」),点选后平铺投同款历史卡并就地重绑,\n  驱逐旧活跃线程使下一轮命中所选会话。多话题群路径不变。\n- 多话题群误发 /clear → 提示仅单会话群可用,不喂给模型。\n- 单会话群 /help 与欢迎卡按管理员列出 /clear、/resume(/resume 另受后端 resume 能力约束)。\n\ntypecheck + build 干净,全量测试通过(+7 卡片用例)。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(bot): 单会话群支持 /clear 与 /resume(仅管理员)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-08T13:05:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9e47f466a8ce5c3d77df0c852186b81ad1e52568",
          "body": "Split the install section into direct commands and an AI-agent handoff prompt, then replace the bare Bilibili link with a rendered clickable cover image.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(readme): add install demo card",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-07T14:08:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3ff9aa144fdb80c5284d5ebc5c1abcbc4381aec1",
          "body": "Replace the quick install section with a copy-ready local setup prompt and add the Bilibili install demo link.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(readme): update install handoff prompt",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-07T14:02:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "16c29fbb6cc616a808098676e07481ebf80bd020",
          "body": "Expose https://bridge.vonvon.cc in the README badge area and docs links.\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(readme): add official website links",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-07T13:56:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "670f0cf5676061b3fd756192318afe11298e4fe4",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.6.5",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-03T16:51:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0be9ea1435e48d24b2d285b0d32467495dd67b7b",
          "body": "「等待确认」是状态词、⏳ 沙漏图标又强化「系统在等」的错觉,但用户按它其实是主动收尾,语义拧巴(社区反馈来回 4 轮才搞懂它作用)。改成动作视角的「✅ 收工」,点后完成态「✅ 已收工」,footer 与代码注释同步。\n\n测试:正向断言换精确串「✅ 收工」;两处「无 reply 窗」改为检查 taskCompletionDone action 不存在,避开标题池里「桥那头收工了」的文本误伤。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(card): 咖啡卡「等待确认」按钮改名「收工」",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-03T16:46:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "66502b34713925a8415166c83b2eb331fefa6a52",
          "body": "反馈:run 卡里 shell 命令超一行就被截到 80 字符看不全,尤其批量\n「N 个工具调用」摘要每行 header-only 截断,开发者无法核对 Agent 到底\n执行了什么。飞书单卡 ~200 组件上限(超了整卡静默丢弃)与 ~30KB/元素\n上限,让「每个工具一个可展开面板」不可行,才被迫压成截断摘要。\n\n- 给 AgentEvent.tool_use / ToolEntry 加 kind(command/file/search/tool),\n  两个 backend 的 event-map 统一赋值,reduce 带进 ToolEntry。\n- 命令类工具面板 body 补出完整\n[…]\n展开不再是\n  「无输出」而是解释文案(codex 不回传搜索结果,直接喂模型作答)。\n\n保持终态「一个折叠 process 面板 + 答案在外」结构不变(可转发、默认\n收起的产品优势)。新增/更新测试覆盖完整命令可见性、批量降级、组件\n护栏、三态与联网搜索。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(card): 工具调用显示完整命令 + COT 式过程观感",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-03T16:28:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "42132a5fa603dbfb70311afed92ace62371b8e35",
          "body": "通读 src/ 全量源码 + git log 重新梳理的项目能力清单/边界/已知缺口,\n作为社区反馈评估 loop 的对照基线;旧设计稿 v1 的多数「非目标」已实现。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: 新增项目现状梳理(2026-07-01,以代码为准)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-07-03T09:42:20Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f73b6a9276ae1ce9f2eb3ed2cc4b6224d250df16",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.6.4",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-30T10:30:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "007a3e213ee587a8fec7bb614f8b2967c5d4aebb",
          "body": "云文档评论:仅管理员可 @;每条评论串独立会话;指令改由每文档工作目录的 AGENTS.md/CLAUDE.md 承载(claude 后端开 settingSources 读取)。支持文档类型 doc/docx/sheet/bitable(多维表格),移除 file;docUrl 按类型映射正确 URL 路径段(sheet→/sheets/、bitable→/base/、doc→/docs/)。DM 设置新增「云文档评论」子卡:后端/模型/推理强度 + 自定义提示词(编辑/重置/保存就地反馈),纯文本回贴 + 评论锚点保护规则。\n\n设置卡:「☕ 咖啡一下」整组(总开关/通知范围/转发后端/离开保活/hooks 修复)从主卡内联抽出为二级子卡,主卡只留入口;各控件改动后停在子卡。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(bot): 云文档评论 @bot 流改造 + 设置卡咖啡子卡",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-30T10:26:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "05f907ccc85744c2cf8a8fd4ad21e9ab1091a5aa",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.6.3",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-29T12:42:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "34b7f7ee2d6b4eebb71bbe69682e476d75c36ae9",
          "body": "DM 项目设置卡新增「🤖 默认模型」子表单(群 /settings 镜像同款入口,均管理员门控),为本项目新话题预设起始模型 + 推理强度。优先级:/model 会话覆盖 > 项目默认 > 后端 isDefault/defaultEffort。\n\npickDefault 改为对后端**实时**模型列表校验:陈旧 / 跨后端 / 该模型不支持的 effort 一律忽略并回落后端默认,自愈、绝不把坏 id 喂给 CLI;只影响新会话,不驱逐进行中 / 已 resume 的会话。新增 test/model-default.test.ts 覆盖 pickDefault 自愈分支 + 卡片自适应 + ctx 路由。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(bot): 项目级「新话题默认模型 / 推理强度」",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-29T12:40:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bf8ef637d89b8ab300765e94285dc7fe440e86da",
          "body": "私聊控制台「项目列表」把全部项目渲染进一张卡,每个项目含一行最多 4 个按钮(展开成 column_set/column/button/plain_text 约 17 个组件)。39 个项目 ≈ 700 组件,远超飞书单卡 ~200 组件上限(错误 300305 element exceeds the limit,平台静默丢弃),点击后无任何卡片返回。\n\n改为分页:每页 8 个项目(实测约 146 组件,稳在安全区),底部加 上一页/下一页 + 第 X/Y 页;页码经 ActionValue.p 透传,越界自动钳到有效页(过期点击 / 删项目后列表变短不会停在空白页)。新增 test/project-list-paging.test.ts 守住分页与单页大小不随项目总数增长。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(bot): 项目列表分页——项目过多撑爆飞书卡片组件上限致整卡静默丢弃",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-29T12:04:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0c475bb5d10ba3e7c61aadbdffdd362709fe8587",
          "body": "- 后端措辞改为 Codex / Claude Code,架构图同步\n- 新增置顶 ⚡ 安装章节,前置条件压成一句话\n- 特性/使用按现功能重写(两后端、☕ 咖啡一下反向桥、多机器人同连)\n- CLI 一览补全命令;删启动/飞书后台配置/故障排查等冗余章节\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(readme): 精简重写——补 Claude 后端/咖啡一下,砍冗余章节",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-23T09:36:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fa2246668789f2957a472540cb5eeb7065cc8f78",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.6.2",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-22T10:23:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b8885d41566b28d6e174a59f78135e144045ff5a",
          "body": "私聊控制台「🩺 诊断」初步诊断区新增一行机器人 open_id(ou_…)。\n复用 buildDoctorInfo 已有的 validateAppCredentials 返回值(bot/v3/info),\n零额外请求;凭据失效/断网拿不到时降级显示「未能获取」,不升橙。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(bot): 诊断卡片展示机器人 open_id",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-22T10:18:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "62c4a560d72859abb9542e2616376c86fbcf1c0b",
          "body": "card 2.0 交互卡片被 bot 接收时,推送事件 / 旧版 content 只给降级占位\n(SDK 归一化成 \"[interactive card]\" 或「请升级至最新版本客户端…」),真正的\n卡片正文与 Base 记录链接都不在里面,codex 收到后无从处理。\n\n命中降级时带 card_msg_content_type=raw_card_content 回查完整卡片,解析\nproperty-wrapped 的 card-builder schema 提取文本+链接(含标题、按钮文案、\n单语言页脚),塞回 msg.content,让 codex 读到「请处理这条记录 [查看…](base链接)」。\n回查失败时保留原行为,不影响其他消息。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(bot): 读取多维表格自动化卡片正文",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-22T10:07:48Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "27e4779c5bd23e8a221d0f19812b053ec1151fdb",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.6.1",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-20T02:21:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c1ede6109d8e8207c87a7b27c89f8122a4b9301d",
          "body": "引用一张卡片再 @bot 时,桥用 im.v1.message.get 拉被引用消息,但\nextractMessageText 对 interactive 类型一律返回 [卡片消息],把内容全丢了。\n\n实测飞书 message.get 永不返回卡片源 JSON,而是降级成类 post 的\n{title, elements:[[节点]]}:1.0 卡片正文完整保留;2.0/CardKit 卡片只剩\ntitle(正文被「请升级客户端」占位替换)。新增 extractCardText 递归解析该\n结构,提取标题+各行可读文本(text/链接/@/note/按钮),丢弃升级占位,提不到\n才回退 [卡片消息]。引用回复与话题上文两条 weave 路径同时受益。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(bot): 回复卡片 @bot 时让 bot 读到卡片内容",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-20T02:16:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "22a7a31812ab7269e9a51b9eec4e4dcf862d3b11",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): 0.6.0",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-18T17:09:41Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3273010b62b194293a5b82e152391046a6e43f66",
          "body": "在初版「hooks 转发」之上做完整产品化:\n\n- 离开判定:锁屏 或 键鼠空闲超阈值即\"离开\";回到电脑/解锁立即收回\n- 离开提示卡:首次离开且有 agent 活动时一次性告知\"已接管\"(唯一带 cwd)\n- 通知范围:全部 / 仅绑定项目 / 不通知\n- 按后端开关:Claude / Codex 各自独立\n- 离开保活:caffeinate -i(顶住系统休眠、屏幕照常熄灭),离开且有任务在跑才开\n- 多问题选择卡:AskUserQuestion 渲染成单表单 —— 每题下拉(单/多选)+ 常驻\n  自定义文本框(填了即覆盖)+ 一次提交;根治旧版\"自定义输入点了没反应\"\n- 完成卡多轮\n[…]\nk 冲突提示;诊断日志 hook-recv\n\nCodex 限制(已文档化,非缺陷):request_user_input 仅 Plan 模式可用,默认模式\n降级为\"完成卡文字 + 回复作答\";其 PermissionRequest hook 也不支持回灌答案。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(cli-bridge): ☕ 咖啡一下 — 离开电脑时把本机 Claude/Codex 接管到飞书",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-18T16:56:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cc18856d20a717e29c7a1b7e73638a11582ea0e8",
          "body": "把本地 CLI agent(Claude Code / Codex)的权限审批、AskUserQuestion 提问和\nStop 任务完成事件经 hook → 单连接 IPC(Unix socket / Windows 命名管道)转发到\n机器人 owner 私聊;away_only 在场检测(macOS ioreg / Windows GetLastInputInfo)\n决定是否打扰,人回到本机即把控制权还回终端。支持飞书回复完成卡续聊、本会话放行\n缓存,以及全局设置卡内联的开关 / hook 安装状态 / 一键修复。\n\nreview 修复:\n- presence: 让 presence.pl\n[…]\n 每次无关设置交互都做 3 次 fs 读。\n\n新增 cli-bridge 全套单测(parser / protocol / store / ipc / hooks / hook-routing /\ncards / config / runtime / service),并覆盖上述修复。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(cli-bridge): 本地 Claude Code / Codex hooks 转发到飞书 owner 私聊",
          "author_name": "alixe-mint",
          "author_login": "alixe-mint",
          "committed_at": "2026-06-18T16:56:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "df0bbaec7df49604bd55c59077acb53e6be8b482",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): 0.5.0",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-17T14:35:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3b301c87b7f37544cf2e1fed4f4b36088d657101",
          "body": "下载死循环根因:installBackendDep 校验失败后 rollback 只 rm 主包目录 + 删 package.json\n条目,**却留下 package-lock.json**;下次 npm i 以为已装、只'added 1 package'、不恢复主包\n→ 校验又失败 → 再回滚 → 永远装不上(实测:backends 里只剩 darwin-arm64+deps、主包/sdk.mjs\n缺失)。修复:rollback 连 package-lock.json 一起删,下次全量重解析。\n\n创建项目后端选择(用户诉求'未装也应显示+提示去下载'):\n- backendOptionsF\n[…]\n藏 → 用户'没地方选'。\n- assertBackendUsable:选了未下载的 npm-ondemand 后端 → 友好提示'去 Web 后端 Agent 页下载'。\n- 新建卡 note 同步。typecheck/build/test(734) 全绿。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(backend): 修安装死循环(回滚清 lock)+ 创建项目时未装后端可见可引导",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-17T14:19:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2ed7409a3a8b6c746b923b6b23fce9f9583f97c7",
          "body": "病根:点下载装 265MB SDK 时,req.on('close')→abort→回滚半装;用户因没明显进度+按钮\n误标'40M'而刷新/切走→把安装杀了回滚→仍显示未下载(实测踩坑)。\n\n- handleBackendInstall 改为 installJobs 注册表:npm 后台跑到底,SSE 断开只摘监听、绝不\n  abort/回滚;重连(再点下载)命中同一 job、回放日志+续看进度,绝不并发重复装;完成后\n  清 job,/api/backends 经文件系统探测即显示已装。\n- catalog approxSizeMB 40→265(按钮显示'约265M',设对预期),detectHint 同步。\n- typecheck/build/test(734) 全绿。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(web): 后端安装脱离 SSE 生命周期(刷新不杀)+ 体积标对(265M)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-17T14:07:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6f83a28d2c42e33f27bfa381e816647b7c18f93a",
          "body": "实测(spike16):query.interrupt() 在阻塞工具(sleep)执行中途会卡死(40s 不返回),只在\n工具调用边界/流式时可靠。故 abort(turnId) 升级:先 interrupt()(暖,流式秒停),若\nABORT_ESCALATE_MS(4s)内该轮没结束→硬 abortController.abort()(线程死→resolveThread\n下条消息 resume 续聊)。runStreamed/runGoal 加 turnInFlight 追踪 + endTurn 清理定时器;\n主动中断的 end/error 统一收为 done(不闪 error)。LIVE 实证:活跃工具中 ⏹ ~4s 有界停止+续聊。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(claude-agent): ⏹ 工具执行中途可靠停止(interrupt 卡 → 升级硬 abort)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-17T13:25:11Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2e454e976350aff08941818d240c71aa990e2fe2",
          "body": "Claude 无 codex 目标引擎,但 agent loop 能在一个 query turn 内自主多步跑完目标:\n- runGoal():发带自主提示的目标 → 流式跑 → 合成 goal_update(active→complete/blocked/budgetLimited)\n  + turn_started + done;tokensUsed/timeUsedSeconds 据实填。capabilities.goal=true。\n- clearGoal():⏹/🎯 终止用 abortController 硬停(spike14 实测工具中途 ~2s 停,远比 interrupt 可靠\n[…]\nclearGoal→线程死→resume 续聊成功。\n- 与 codex 差异(如实注明):codex N 个自动续跑 turn + 原生状态机;claude 1 个自主 turn + 合成状态。\n- typecheck/build/test(734) 全绿。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(claude-agent): /goal 自主目标(goal-like)+ abort 硬停可终止续聊",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-17T00:47:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8013ff5bd882a8ea3554c1b3b17406749cd74980",
          "body": "- package.json:@anthropic-ai/claude-agent-sdk 从 dependencies → devDependencies;\n  tsup.config 加 external(dist 不打包 SDK,验证内部符号 0)。\n- backend/thread:去掉静态值导入,改 loadBackendDep 动态加载(桥/全局/用户私装目录三路探测);\n  query 注入进 thread。已装(任一路径命中)即复用、绝不重复下载(满足用户诉求)。\n- doctor:未装 → installable=true(Web 出「下载」按钮);已装 → ok + 版本。\n- 效果:基础安装更轻;新建 Claude 项目前在 Web『后端 Agent』点一次下载即可。typecheck/build/test(734) 全绿。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(claude-agent): SDK 改为按需下载依赖(不再随桥捆绑)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-17T00:36:28Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "54fadb3c7a49f90a7b4ef9b17eebb2d5e0fd8dc2",
          "body": ".bka-tbl 用 overflow:hidden 做圆角会裁掉最后一行向下弹出的菜单(Claude 行「检查更新」被切);\n末行 .menu 改 top:auto + bottom 向上展开即避开,圆角不变。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(web): 后端 Agent 表格末行下拉向上展开,避免被 overflow:hidden 裁掉",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-17T00:25:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "43f50723db1a6b42541cb60f46ef94640c8cc66f",
          "body": "/context:result 消息无 model → 窗口曾显示「未知」。turn 末调 query.getContextUsage()\n取权威 totalTokens/maxTokens(= 原生 /context,opus[1m]→1M);event-map 回退也从 init 的\nmodel 取窗口(不再用缺失的 result.model)。\n\n/compact:原标 compact=false 过于保守。Claude Code 原生支持 /compact——thread.compact()\n发 \"/compact\" 经 CLI 拦截执行、排空到 result,compact_boun\n[…]\nundary→context_compacted(自动压缩通知)。\n\nLIVE 实证:full 档 state.usage.window>0(窗口已知);compact() 端到端返回合法结果不抛错。\ntypecheck/build/test(734) 全绿。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(claude-agent): /context 显示真实窗口 + 支持原生 /compact",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-17T00:11:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "149ef07b20858a969e24a4fbba0405be1e6d2a38",
          "body": "- listThreads → SDK listSessions({dir:cwd});readHistory → getSessionMessages 折叠成 turns。\n  读 ~/.claude/projects/<cwd-hash> 本地存储(与 `claude -r` 同源、零 API 成本)。\n- capabilities.resume 开为 true:飞书 /resume 能列出本机 claude 手开的会话;桥建会话(默认\n  persistSession+cwd)也出现在 claude -r(spike9 实证双向可见)。\n- 新增 history.ts 纯映射(mapSessionSummary/foldSessionMessages)+ 单测(7)+容错冒烟(3);\n  导出 event-map.toolTitle 复用。typecheck/build/test(732) 全绿。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(claude-agent): /resume 与 claude -r 双向会话发现",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-17T00:02:24Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fe2ee19d9154175bc5a0510becd108a68b0090f5",
          "body": "- buildWelcomeCard 加 agentName 参数(缺省 Codex,向后兼容):欢迎语「欢迎使用 X Bridge…\n  驱动本机 X 干活」随后端切换。\n- onboardGroup 从 catalogById(backend).displayName 取名,同时驱动群菜单「🤖 X」。\n- 补测试:Claude 欢迎卡文案不含 Codex;claude-agent 群菜单为「🤖 Claude」。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(onboarding): 欢迎卡 + 群菜单文案按后端展示名区分(Codex/Claude)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-16T23:56:10Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0d421c264ebc0b2e8afa4991748e9f58d94c8bf2",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(claude-agent): 记录 qa 读限不可行(spike8)与验收/飞书 runbook 定稿",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-16T18:45:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d16387e0fd0cbabb756e10ca56cbddbcaa7057d7",
          "body": "- claude-permission.test.ts(6):三档→SDK 选项映射,含 allowUnsandboxedCommands:false\n  堵逃逸、qa denyWrite[cwd]、network off 移除联网工具、fail-closed 不变量。\n- claude-event-map.test.ts(8):SDKMessage→AgentEvent,text/thinking delta+收尾、\n  itemId 关联、工具/工具结果、result→usage+context_usage、多块独立 id。\n- 零 API 成本;全套 720 passed。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(claude-agent): 补 permission/event-map 单元测试(纯函数,锁安全映射+事件映射)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-16T18:41:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5f33b92b15fdeda279939beddb3e031220a866ec",
          "body": "安全(spike 实证 macOS):\n- write→bypass+sandbox(allowUnsandboxedCommands:false):写入锁 cwd、内核级、堵 dangerouslyDisableSandbox 逃逸。\n- qa→再加 filesystem.denyWrite[cwd]+禁写工具:逼模型多手段写盘均失败,真只读。\n- failIfUnavailable:true 沙箱起不来即报错(fail-closed)。弃用 canUseTool(与 filesystem 同用触发 SDK ZodError)。\n- 已知差异:qa 读取尚未硬限 cwd(Codex 有),已\n[…]\n计费):full 流式/多轮/⏹中断/qa只读。\n- full/中断/qa 稳过;多轮经 spike 复刻 10s 通过,LIVE 偶发超时系 API 529 过载非代码问题(已注明+放宽超时)。\n- typecheck/build/test(706) 全绿。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(claude-agent): 三档权限改用纯 OS 沙箱 + 加 LIVE 集成测试",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-16T18:39:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d69e3c0cb587f365f8749386705abf5e24faf0dd",
          "body": "- src/agent/claude-agent/{event-map,permission,thread,backend}.ts:\n  以持久 streaming-input query() 驱动 Claude Code,单进程多轮复用暖进程;\n  SDKMessage→AgentEvent 映射(text/thinking delta + 工具块 + usage);\n  三档权限 full→bypass / write→沙箱+canUseTool 限 cwd 写 / qa→只读,fail-closed。\n- 注册到 index.ts REGISTRY + catalog.ts(id cla\n[…]\nompact/resume(历史卡) 暂不支持,已声明 false 并抛清晰错误。\n- 更新 backend-catalog/backend-registry 测试为 codex+claude 新现实;typecheck/build/test(706) 全绿。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(claude-agent): 新增 Claude Agent SDK 后端(事件映射/线程/三档权限)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-16T18:06:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a29663dd27712491ac9b310f9bf6c4d51fb1125f",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.4.3",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-16T16:25:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ae2ab144c4f4342638c5a55553e9ca34dc2de2df",
          "body": "application.bot.menu_v6 原先对任意 event_key 都只回首页菜单卡。改为按 key 路由:\nnewProject / projects / settings / usage / doctor / reconnect / update 各自直达\n对应卡,其余(含空 key)回退首页卡,兼容「只配一个入口」与旧配置。usage / update\n走两阶段(先落地 loading/checking 卡再原地更新);抽 buildDoctorInfo 让 DM.doctor\n与菜单共用探测;reconnect 从 markdown 文本统一成 buildReconnectCard 卡。私聊发消息\n→首页卡(handleDmConsole)链路不变。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(bot-menu): 底部菜单 7 个入口按 event_key 直达对应卡",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-16T16:23:21Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1ddf14397f155343934a271c6a5b3fe474dbdf8f",
          "body": "模型显示(许愿池:卡片显示当前模型,省得忘了切回贵模型):\n- 设置项升三档「关闭 / 仅输出时 / 始终」,默认「仅输出时」\n- 运行卡右下角脚注「模型 · 推理强度」,仅给 effort 词按档位着色\n  (低黄/中绿/高浅紫/极高深紫),模型名保持灰\n- 仅输出时档生成完即收起、始终档终态卡保留、off 不显示\n- schema:showModel 升 ModelDisplayMode 三态,兼容历史布尔\n  (true→always、false→off),默认 running\n\n设置卡重做(方案 A):\n- 按「📤 输出展示 / ⏱ 运行控制」分区,每项加灰字说明(自解释)\n- 抽 s\n[…]\n header 副标题\n\n⏹ 终止键移回运行卡底部(撤销 b3eea45 的置顶):\n- 顶置原为 e2e 够得着;真人视线跟随底部最新输出,故移回\n- goalEnding 恢复「提示在前、按钮在后」顺序\n\n测试:模型三档脚注 + 档位映射 + 终止底部断言\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(card): 模型显示三档 + 设置卡分区重做 + ⏹ 移回卡片底部",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-16T16:11:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c899d950304b1e834a521646b84c1e714224bbe4",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.4.2",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-15T16:33:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "29fdbcafba89e6bbe0f59201c78de73c5e74d135",
          "body": "- cards.ts: linkButton 加 size;新增 actionsFixed(固定宽度左对齐行)/splitRow(控件+旁注两列);card() header 支持 text_tag_list\n- dm-cards.ts: buildDmMenuCard 加 🌐 网页控制台(直接开 127.0.0.1 本机控制台,非本机打不开,旁注说明);按钮固定宽度配平对齐(上152/下112,总长相等)+size large;header 绿色版本徽章;forward:false\n- web/discovery.ts: webConsoleUrl() 读发现文件拼本机控制台 URL\n- handle-message.ts / dm-console.ts: 各 buildDmMenuCard 调用点注入 webConsoleUrl()+bridgeVersion()\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(dm-card): 私聊菜单加「🌐 网页控制台」入口并美化菜单卡",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-15T16:28:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "73a1ddc8c41e98053e8e550e805122f9c53b0cec",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.4.1",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-15T12:34:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f2959096942a5a62aa088f29ca7baa696b93e120",
          "body": "weaveSender / weaveQuote / weaveThreadHistory 结尾都是「block 在上、正文在下、空行分隔,正文空时只留 block」,重复 3 遍。抽成 prependBlock 单点维护。纯重构,273 测试全绿。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(context-weave): 抽 prependBlock 收敛三个 weave 的拼接逻辑",
          "author_name": "SanQuan",
          "author_login": "ZhongBiao-zheng",
          "committed_at": "2026-06-15T12:22:28Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f881e024b07561bd4ae71813d09e40cfc8207632",
          "body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(card): lock <at> mention passthrough in renderRichText",
          "author_name": "SanQuan",
          "author_login": "ZhongBiao-zheng",
          "committed_at": "2026-06-15T12:22:28Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1d1126fcb5bafcabdbf512777b99c3543ed40137",
          "body": "…ontext",
          "is_bot": false,
          "headline": "feat(intake): weave sender identity into every codex turn via ingestC…",
          "author_name": "SanQuan",
          "author_login": "ZhongBiao-zheng",
          "committed_at": "2026-06-15T12:22:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "77ed3cc37d797d4f1a127fb45719ecb36b6ec75e",
          "body": "… the prompt",
          "is_bot": false,
          "headline": "feat(context-weave): add weaveSender to fold sender open_id+name into…",
          "author_name": "SanQuan",
          "author_login": "ZhongBiao-zheng",
          "committed_at": "2026-06-15T12:22:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0c9f967b1aa46d45d4db2e6b0a0612a283787835",
          "body": "bump 0.3.12 → 0.4.0;移除 @agentclientprotocol/sdk 与\n@anthropic-ai/claude-agent-sdk 两个依赖(随 Claude 两后端一并下线)。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): 0.4.0",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T15:43:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "714a26f54bc6ce3b5bbf8b911582a11d7a90f4b5",
          "body": "两个 Claude 后端尚未上线(一直由 hidden 闸隐藏),决定不再随版本携带。\n彻底移除其实现、注册/目录条目、相关测试与配置,只保留 codex-appserver\n一个后端 + 通用后端抽象(catalog/registry/backend-loader/installer 等\n基础设施保留,便于将来再挂新后端)。\n\n- 删 src/agent/acp/、src/agent/claude-sdk/ 及其单测 + fixtures\n- index/catalog/detect 仅留 codex-appserver;detectAgents 只探 codex\n- backendForP\n[…]\ncpCommand()\n- 清理 README / Web 控制台 / 卡片 / 启动文案对 Claude 后端的引用\n- 16 个共享后端测试改为 codex-only(保留通用机制覆盖)\n\ntypecheck / 691 tests / build 全绿。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(agent): 移除 claude-sdk / claude-acp 两后端",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T15:43:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b81810df4a4b6c68c3d1150420b3197e7ee237db",
          "body": "- 「最省事」一节改为 Web 优先:给 Codex/Claude 的提示词内联自包含,\n  让其装好后跑 `web` 并用 open/start/xdg-open 在浏览器打开控制台,\n  之后扫码加机器人 / 启停 / 重启 / 更新全在网页里点。\n- Web 控制台一节补「从零到跑起来(浏览器路径)」,定位为推荐管理入口。\n- 修正控制台默认端口(7866 → 51847,与 DEFAULT_WEB_PORT 对齐)。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(readme): 主推 Web 控制台作为安装与管理入口",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T14:56:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "43445e6b0be19d04fda333da095db3d1f6a1d0fa",
          "body": "把未跟踪的工作素材(_root_contact_sheet.jpg、new/)归到 docs/assets/_local/,\n加 gitignore 规则,保持发布前工作区干净。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: ignore docs/assets/_local 本地素材",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T14:45:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fa1ae9429fa4990954ab08d0a44af3b03e245109",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.3.12",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T14:38:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "86ca8e1a031a57b191bf8913bc745c69c39cd5e7",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.3.12-test.3",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T14:27:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e96ea3afc1e55d1a9f5ed2f0de3c4af94a7132f8",
          "body": "postModelCard 硬编码 reply_in_thread=true,导致单会话群里 /model 的模型卡被甩进一个新\n话题,而不是直接出现在会话里。改成与 postContextCard 一样吃 inThread 形参:单会话群传\nfalse(扁平引用回复,卡片直接出现在会话),话题内传 true(卡片发在当前话题)。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(bot): /model 单会话群扁平回复,不再误起话题",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T14:27:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "898883b4ccf9e227c2280e1986d8098c3e94669c",
          "body": "飞书 applink(client/bot/open?appId=,feishu/lark 各自域名)在飞书客户端直接拉起与该\nbot 的私聊——等同开发者后台「创建成功 → 打开应用」那条链。加在 bot 概览卡 + 向导完成步。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(web): 机器人页 / 接入完成加「在飞书中打开机器人」按钮",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T14:27:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9434fdd68200d1d9cb6e407519abc28d8e663a07",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.3.12-test.2",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T14:11:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e982076b9ee82c2f24394d0373d58a5a56ec229e",
          "body": "- registerBot / registerBotByQr 在只读预览(readonlyPreview)下抛 NotWiredYetError:\n  加机器人是写操作,必须先有 daemon 在跑(前台 run 的引导控制台本身就是在跑的 daemon,\n  第一个 bot 在那里加)。server 把同步抛映射成 501;QR SSE 走 .catch。\n- createReadonlyAdminService 现接受 applyUpdate:没启动时能做的写就「启动」+「更新」。\n  web.ts 注入 applyUpdate,只读预览也能升级 npm 包。\n- 测试:registerBot 委托测试改用 createAdminService;新增只读预览 registerBot 抛错断言。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(web): 没启动只读——加机器人必须先有 daemon 在跑;只读预览放行更新",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T14:11:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "790a87e8a9914ae7adcb2aa1a443bbf7c855be74",
          "body": "- 完成步只剩**一处**重启入口:主按钮「重启使其上线」(直接重启) + 次按钮「稍后再重启」;\n  去掉重复的自动确认弹窗、去掉「新建项目/拉群/@」那套啰嗦引导(让人误以为是前置条件)。\n- 接入检测页删掉「待拉起上线」中间项——加入活跃集全程静默(pollWizSetup 已自动做)。\n- 扫码创建页加三步说明:扫码 → 飞书里确认创建 → 回本页自动进入②接入检测。\n- 「添加机器人」改走 tryAddBot:daemon 没在跑时不开向导,弹窗引导先启动(没启动只读)。\n- daemon 卡片常驻「🔄 检查更新」按钮——更新入口始终可见(不管跑没跑)。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(web): 接入向导收尾精简 + 加机器人需先启动 + 检查更新入口(前端)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T14:11:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7445db16f3674f5585f911ca3ccd64aa67955f7b",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.3.12-test.1",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T13:51:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a7de4636890aeedaa26747f04eb087c20cc53c21",
          "body": "根因:旧逻辑 51847 被占就退临时端口、且每进程随机 token,导致重启/预览→daemon 切换后\n端口和 token 都变,浏览器那条 URL 失效(换页 / 401)。\n\n- daemon(mount.ts)是控制台权威持有者,始终抢规范端口 51847:重启时老实例先 close()\n  释放,新实例短重试(~5s)抢回同一端口;实在抢不到才退临时端口兜底。\n- 只读预览(web.ts)改用临时端口,绝不抢 51847;点启动后 daemon 占 51847,前端 live\n  轮询自动跳过去,之后一直稳定在 51847。\n- token 持久化到 0600 的 web-token 文件(stableWebConsoleToken),预览与 daemon 共用,\n  重启后旧 URL 的 token 仍有效,不再 401。与 web-console.json 同信任域;删文件即轮换。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(web): 控制台端口与 token 稳定——重启/启动不再换端口甩新页",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T13:51:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "61c6bc18d8e42d45fdde77299066b33378a7a178",
          "body": "- 新 bot 默认就加入活跃集(pollWizSetup 一次性 PATCH enabled),不再让用户点按钮 /\n  复制 bot use+start 两条命令。完成步弹窗确认重启(daemon 没跑则启动)才真正拉起。\n- 事件订阅无法可靠检测(长连接订阅在已发布版本里的体现不稳定):接入向导与 bot 接入\n  诊断都改成纯提醒(ℹ️ 请自行去「事件与回调」核对),不再下 ❌「缺事件」结论、不再\n  拦「下一步」、不再要 application.app_version:readonly 那个 scope。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(web): 接入向导默认加入活跃集 + 完成确认重启;事件订阅改纯提醒",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T13:51:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "79cbe2bf6891c186ebda338bb3408f5f55765afa",
          "body": "probeAllBackends 改走 visibleCatalog(原来用 backendIds 全量),与 listBackendCatalog /\nhost.doctorBackends 同口径。补上 790014b 漏掉的两处用户可见面:bot 接入诊断「后端环境」\n+ 宿主机体检,不再露出 Claude Code (Agent SDK) / Claude (ACP)。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(backend): 接入诊断 / 宿主机体检也隐藏 claude 两后端",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T13:51:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "268bf272c390b0fdbb86cc1456dffd82547b606f",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 0.3.12-test.0",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T13:23:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "93283b6c0aff544264aca3bf3eba29580a657e5e",
          "body": "- 切换机器人启用:成功后若 daemon 在跑,弹窗确认是否立即重启,确认即自动重启(复用\n  confirmDialog + /api/daemon/restart,省去终端 restart)。\n- 接入向导「长连接未建立」:加「一键启用并拉起」按钮(启用→daemon 在跑确认重启、\n  没跑直接启动),保留手动命令兜底。\n- web 命令只读预览分支也调 openUrl 自动打开浏览器(此前只有 live daemon 分支会开)。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(web): 活跃集切换/接入向导一键启用并重启 + web 只读预览自动开浏览器",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T13:22:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ae1ab210e3de8bf024554dfae38af91d36d842c8",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: sync package-lock(claude-agent-sdk 归位 devDependencies)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T13:22:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b3df3bcdeb5ecc240dea56a72832817fd17fd770",
          "body": "- launchd uninstall:先 rm plist 再 bootout。停止走的 detached helper 其实仍在\n  launchd job 里(detached/setsid 逃不掉 job 成员关系),bootout 会连它一起拆,旧\n  顺序里 rm 排在 bootout 之后被跳过 → plist 残留 → 下次登录又自启。\n- doStop:按「已安装」而非「在跑」判是否卸载,堵住 KeepAlive 在重启窗口被读成\n  not-running → 裸 SIGTERM → 立刻重生的「停止不了」;adapter 段兜 try 不漏自托管兜底。\n- supervisor:补注入 stopDaemon(多 bot 模式漏了它,Web 点停止抛 501,文案误导成\n  「只读预览」)。三处 live 控制台现都齐了。\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(daemon): Web「停止」对 start/多bot daemon 时灵时不灵",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T13:22:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "790014b8d16714904729397aff2802c0cc15dca7",
          "body": "darkened-andesaurus 全量(多后端内核 + Web 全局控制台 + 渲染/性能/健壮性/可发现性\n硬化)已 ff 进本分支;此提交加「用户不可见闸」:claude-sdk / claude-acp 对用户\n全隐藏,仅 codex 可见可选。两后端代码与注册保留(catalogBackendIds 仍含三条、\n与 REGISTRY 配对不破),验证完毕删 catalog 条目里的 hidden 即点亮,零返工。\n\n曝光过滤集中在 4 个用户可见面 + 1 处卡片:\n- catalog.projectCreatableBackends —— Feishu 新建/绑定卡的后端选择器\n[…]\n— 只剩 codex 时返回 [],卡片回到「无后端概念」形态\n\n新增 catalog.visibleCatalog()(滤 hidden)作用户可见面单一取数口。\ntsc 干净 · vitest 752 绿(7 处「claude 可见」断言改为隐藏契约 + 4 条 gate 正测)。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(backend): hickory 集成——隐藏 claude 两后端(用户不可见闸·保留注册可点亮)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T12:45:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "738e6c9232f268c39d76a94cf7975404d3008047",
          "body": "此前绑定已有群的卡片把后端下拉写死 backendOptionsFor('qa'),而 claude 系仅支持\nfull 档 → qa 过滤面下被剔除 → 加机器人到自己已有内部群时根本选不了 Claude(e2e\n实测发现,只能 codex)。\n\n改:绑定卡列「全后端」(backendOptionsFor('full') = 已下载的都列);默认仍是 Codex\n(列表首项),绑定后按所选后端定档——\n  - codex / 未选 → bindModeFor 返回 undefined → 沿用 joinExistingGroup 的 qa 只读\n    默认(外部群安全不变);\n  - cl\n[…]\n选 Claude 则以完全访问档绑定」。\n\nbot.added 首发的绑定卡 + 提交重渲染两处都改。bindModeFor 导出 + 单测覆盖\n(codex/未选→qa 默认、claude→full 且 assertBackendUsable 放行、未知 id→undefined)。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(card): 绑定『已有群』卡也能选 Claude 后端(按所选后端定档)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T04:29:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f630512bd1abefbc25d458667d2b821ea8ec0e86",
          "body": "e2e 在三测试群实测发现的两处一致性缺口(A/B 组核对的延伸):\n\n1. 欢迎卡(每个群第一眼的「使用说明」)此前硬列 /goal /resume /compact,对 claude\n   两后端推销了点了不支持的命令——之前只修了 /help,漏了 welcome card。现复用同源\n   HelpCaps 按后端裁剪:claude-sdk 列 /compact(已实现)不列 /goal /resume;\n   claude-acp 三者都不列(话题内只剩「/context → 看上下文」);codex 全列。\n   onboardGroup 用 createBackend(proje\n[…]\n盾的假信号(e2e 实测)。三处派发点(单会话/话题内/主群区)改为:先查 goalCapable,\n   不支持就直接回执「当前后端不支持 /goal,直接 @我派活即可(Claude 每轮本就 agentic)」\n   ——不加 reaction、不空跑 reserved run。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(card): 欢迎卡按后端裁剪 + /goal 不支持时不留 OKR 假信号",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T02:50:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "59382cbf037a6df1a1e537b1a5e67122b6e237cd",
          "body": "之前 claude-sdk 是「最小切片」:/context 不报上下文百分比、/compact 硬 throw。\n但 Agent SDK 本就支持这些(SDKResultSuccess.modelUsage[*].contextWindow +\n\"/compact\" slash 命令 → status[compact_result]+compact_boundary)。e2e 实测对齐:\n\n- /context:事件映射从 result.modelUsage 取最大 contextWindow,补发 context_usage\n  → /context 与跑卡进度条显示真实「已用/窗口」%(\n[…]\n的 /context 自相矛盾 → 成功时返回 usage:null,卡片走\n  「发下一条消息后 /context 看占用下降」诚实兜底,下一轮 context_usage 给真实新占用。\n\ngoal/steer/resume 仍硬守卫(未实现),保持清晰 notSupported。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(claude-sdk): 对齐 /context 与 /compact —— 不再一刀切 notSupported",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-14T02:49:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "063b82d0284f0dffa62b4ae183cd1ebca5d9dada",
          "body": "三后端一致性审计收口:/help 速查卡此前对所有后端硬列 /goal、/compact、/resume,但\nclaude-sdk / claude-acp 的 capabilities 把这三项标 false(能力守卫会拒)——claude\n用户列了点了才发现「不支持」,与 Codex 体验不一致。\n\nbuildHelpCard 加可选 caps 参数(goal/compact/resume),按能力裁剪三个 scope 的清单;\n缺省 undefined ⇒ 全列(codex 不声明 capabilities 的既定语义,向后兼容)。postHelpCard\n传 backendFor(pr\n[…]\npported 守卫且 /resume·/compact·/goal 的 throw\n均被 surfaced;/model 卡与本次 /help 裁剪消除了「列了/显示了却用不了」的不一致。\n\n+6 单测;现有 /goal 可发现性测试(默认全列)不受影响。740 全绿,tsc 干净。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(card): /help 按会话后端能力裁剪命令——claude 不再列点了不支持的命令",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-13T18:31:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0712697c6821db8de473debcfd56f801ae61feb2",
          "body": "用户反馈「Claude 的切换模型体验和 Codex 不一致」:Claude 卡上是「Claude Sonnet ▾ +\neffort:中 ▾」,但 claude-sdk / claude-acp 都 supportedEfforts:[]、运行期忽略 effort\n——那个 effort 下拉点了毫无作用。根因:buildModelCard 在 effort 为空时**回退成假的\nlow/medium/high**。\n\n改为按能力自适应(三后端同一张卡,能调的给控件、不能调的给清晰说明):\n  - effort 下拉只在当前模型真有 supportedEfforts 时出现(Codex 保持\n[…]\n一句「该后端不调节推理强度」;\n  - claude-acp(单模型 + 无 effort):纯信息卡 + 明确「不支持在此切换,由订阅版\n    Claude Code 自身配置决定」。\n\n+4 单测覆盖三后端形态 + hidden 模型不计入多模型判定。734 全绿,tsc 干净。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(card): /model 卡按后端能力自适应——Claude 不再显示点了没用的 effort 下拉",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-13T18:17:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2c8c3a7533c1abf44acdcfc09a256b650a76c2d5",
          "body": "bug B:claude-pty-acp 的 bin 用 `npx tsx` 起,spawn 出来是 npx→tsx→node→claude\n一棵树;npm/npx 不转发信号给孙子,旧版 close() 的 this.child.kill('SIGTERM') 只打到\nnpx 外壳 → node 及它经 PTY 拉起的 claude 全变孤儿(实测满地 claude-pty-acp 孤儿树,\n每次 doctor 检测/会话结束都漏)。\n\n修:platform/spawn 加 killProcessGroup——POSIX 用负 pid 杀整组(child 以 detached\n起即自成进程组\n[…]\nllProcessGroup\n→ STILL ALIVE: NONE,claude 同被回收。+6 单测(负 pid 组杀 / 退出不补杀 / 超时 SIGKILL /\nESRCH 收手 / 非 ESRCH 回退单杀 / Windows taskkill)。730 全绿,tsc 干净。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(acp): daemon 关闭/会话结束不留孤儿后端进程树(进程组杀)",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-13T18:13:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b377d178b7947e812a455666587f8a9923e117a4",
          "body": "真因(实测定位,非 claude 解析问题):node-pty 1.1.0 的 macOS prebuild\n`spawn-helper` 经 `npm install --prefix` 装进用户私装目录后丢了可执行位(0644,\nnode-pty 历史打包回归)。node-pty 在 macOS 上靠它经 posix_spawnp 起 PTY 子进程,\nspawn-helper 不可执行 → 每个 ACP session 必挂 posix_spawnp failed,飞书端只看到被\nJSON-RPC 吞掉的「ACP 后端启动失败:Internal error」。\n\n治本(native-he\n[…]\nspawnp failed → 跑生产\nfixNativeHelperPerms → NEWSESSION OK。+13 单测(errMsg/startupHint 字段提取 6 +\nfixNativeHelperPerms 真实 chmod 5 + 余)。724 全绿,tsc 干净。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(acp): 修「Internal error / posix_spawnp failed」真因 + 错误透出",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-13T18:03:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e28a6287c733dcd3cf636e22fee0095438ee6202",
          "body": "旧 doStop 在 !isServiceRunning() 时直接 return:手动 run / nohup / 引导控制台 /\n多 bot supervisor 全是「自托管」(不在 launchd/systemd 里),launchctl bootout 对\n它们是空操作 → 用户在 Web 点「停止」毫无反应(web 还回 202「停止已发起」更误导)。\n\n修:doStop 两条路一起走——service 托管的照旧 uninstall;另按 web-console.json 记的\npid 给自托管 daemon 发 SIGTERM,触发它自身的优雅退出(supervisor 级联 \n[…]\n SIGKILL 兜底。\n\nstopSelfHostedDaemon 依赖注入(readDaemonPid/kill/sleep/grace),6 个单测覆盖:无\ndaemon / 指向自己 / 已死残留 / 优雅退出 / 卡死强杀 / SIGTERM-ESRCH 竞态。绝不真杀进程。\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(daemon): Web 点「停止」对自托管 daemon no-op → 真能停",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-13T17:52:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "96cd0067fa2f9e05462512914fb5cef5e63d7a2d",
          "body": "根因:只读预览(web)占着 51847,用户点「启动」拉起的 daemon 退到临时端口,\n其可写控制台不在用户当前页 → 看着「运行中」却处处只读、点下载不动。\n\n- 预览检测到 daemon 已起就自动把页面带去可写控制台(server /api/console/live +\n  前端横幅自动跳转),端口在哪、要不要重开都不用用户操心;daemon 自身不注入\n  liveConsole → 永不自跳成环\n- 扫码创建网络/TLS 错误友好化:socket 断连/ECONNRESET/超时等 → 中文「连不上飞书\n  开放平台,检查网络/VPN/代理后重试」,不再把英文原文甩给用户(Qr\n[…]\n可增删、列表会变长)\n- launchd/systemd 等服务管理器名 → 人话(macOS · 开机自启)\n- 后端列表去掉体积列只留版本,详情去掉体积格(下载按钮仍带体积提示)\n- 启动弹窗去掉端口术语;server 5 处 daemon 用户文案 → Feishu Bridge\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(web): 修「在跑却不能下载」只读预览陷阱 + 仪表盘多处打磨",
          "author_name": "Clay",
          "author_login": "ClayCheung",
          "committed_at": "2026-06-13T17:13:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 37,
      "commits_last_year": 263,
      "latest_release_at": "2026-07-18T02:54:42Z",
      "latest_release_tag": "v0.6.10",
      "releases_from_tags": false,
      "days_since_last_push": 2,
      "active_weeks_last_year": 8,
      "days_since_latest_release": 5,
      "mean_days_between_releases": 3.1
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 50,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@modelzen/feishu-codex-bridge",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "feishu",
            "lark",
            "codex",
            "app-server",
            "cli",
            "bridge",
            "bot"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@modelzen/feishu-codex-bridge",
          "is_deprecated": false,
          "latest_version": "0.6.10",
          "repository_url": "https://github.com/modelzen/feishu-codex-bridge",
          "versions_count": 52,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 2419,
          "first_published_at": "2026-05-29T13:30:27.408000Z",
          "latest_published_at": "2026-07-18T02:54:37.002000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 5
        }
      ]
    },
    "popularity": {
      "forks": 12,
      "stars": 41,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-06-04",
            "count": 1
          },
          {
            "date": "2026-06-08",
            "count": 2
          },
          {
            "date": "2026-06-09",
            "count": 1
          },
          {
            "date": "2026-06-12",
            "count": 1
          },
          {
            "date": "2026-06-18",
            "count": 1
          },
          {
            "date": "2026-06-24",
            "count": 1
          },
          {
            "date": "2026-06-25",
            "count": 1
          },
          {
            "date": "2026-06-27",
            "count": 1
          },
          {
            "date": "2026-07-09",
            "count": 1
          },
          {
            "date": "2026-07-10",
            "count": 1
          },
          {
            "date": "2026-07-23",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 12,
        "total_forks": 12
      },
      "star_history": null,
      "open_issues_and_prs": 4
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 263786,
      "source_files_sampled": 210,
      "oversized_source_files": 4,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@larksuiteoapi/node-sdk",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.65.0"
        },
        {
          "name": "commander",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^12.1.0"
        },
        {
          "name": "cross-spawn",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^7.0.6"
        },
        {
          "name": "qrcode-terminal",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.12.0"
        }
      ],
      "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": 2,
        "merged_prs": 2,
        "open_issues": 2,
        "closed_ratio": 0.333,
        "closed_issues": 1,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "ClayCheung",
          "commits": 222,
          "avatar_url": "https://avatars.githubusercontent.com/u/19822342?v=4"
        },
        {
          "type": "User",
          "login": "ZhongBiao-zheng",
          "commits": 4,
          "avatar_url": "https://avatars.githubusercontent.com/u/54110425?v=4"
        },
        {
          "type": "User",
          "login": "alixe-mint",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/190820136?v=4"
        }
      ],
      "contributors_sampled": 3,
      "top_contributor_share": 0.978
    },
    "quality_signals": {
      "has_ci": false,
      "has_tests": true,
      "ci_workflows": [],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "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": null,
            "reason": "no workflows found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 5,
            "reason": "dependency not pinned by hash detected -- score normalized to 5",
            "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": null,
            "reason": "No tokens found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "43 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "fe0f67d526b538afa26b0cb159d55e063f8cc28f",
        "ran_at": "2026-07-23T11:42:48Z",
        "aggregate_score": 1.8,
        "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-21T02:18:30Z",
      "oldest_open_prs": [
        {
          "number": 2,
          "created_at": "2026-06-04T13:54:16Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 7,
          "created_at": "2026-07-10T03:53:50Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-06-18T16:56:05Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": [
        {
          "number": 1,
          "created_at": "2026-06-04T04:15:35Z",
          "last_comment_at": "2026-07-18T04:43:50Z",
          "last_comment_author": "ClayCheung"
        },
        {
          "number": 6,
          "created_at": "2026-07-04T13:30:36Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/modelzen/feishu-codex-bridge",
    "host": "github.com",
    "name": "feishu-codex-bridge",
    "owner": "modelzen"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 51,
      "inputs": {
        "security": 18,
        "vitality": 76,
        "community": 46,
        "governance": 48,
        "engineering": 58
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 76,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 60,
            "inputs": {
              "commits_last_year": 263,
              "human_commit_share": 1,
              "days_since_last_push": 2,
              "active_weeks_last_year": 8
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 2 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "8/52 weeks with commits",
                "points": 5.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "263 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 263
                    }
                  }
                ],
                "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": 37,
              "latest_release_tag": "v0.6.10",
              "releases_from_tags": false,
              "days_since_latest_release": 5,
              "mean_days_between_releases": 3.1
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "37 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 37
                    }
                  }
                ],
                "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 ~3.1 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 3.1
                    }
                  }
                ],
                "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": 46,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "at_risk",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 35,
            "inputs": {
              "forks": 12,
              "stars": 41,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "41 stars",
                "points": 26,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 41
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "12 forks",
                "points": 8.7,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 12
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "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": 56,
            "inputs": {
              "packages": [
                "@modelzen/feishu-codex-bridge"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 2419
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "2,419 downloads/month across npm",
                "points": 45.1,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 2419,
                      "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": 48,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 17,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 3,
              "top_contributor_share": 0.978
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 98% of commits",
                "points": 0.5,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 98
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "3 contributors",
                "points": 4.1,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 54,
            "inputs": {
              "merged_prs": 2,
              "open_issues": 2,
              "closed_issues": 1,
              "issue_closed_ratio": 0.333,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "33% of issues closed",
                "points": 15.6,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 33
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "2/2 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 2,
                      "decided": 2
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 37,
            "inputs": {
              "followers": 1,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "modelzen",
              "public_repos": 3,
              "account_age_days": 97
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "1 followers of modelzen",
                "points": 2.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 1,
                      "login": "modelzen"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "3 public repos, account ~0 yr old",
                "points": 4.9,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 3
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "@modelzen/feishu-codex-bridge"
              ],
              "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": "52 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 52
                    }
                  }
                ],
                "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": 58,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "at_risk",
            "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": 30,
            "inputs": {
              "has_ci": false,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "topics": [
                "claude-code",
                "codex",
                "feishu",
                "lark"
              ],
              "has_wiki": true,
              "homepage": "https://bridge.vonvon.cc",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://bridge.vonvon.cc",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "4 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "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": 18,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Dangerous-Workflow, Packaging, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "dangerous_workflow",
                    "packaging",
                    "signed_releases",
                    "token_permissions"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 18,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 13,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 5,
              "scorecard_aggregate": 1.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": "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 workflows found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 5",
                "points": 2.5,
                "status": "partial",
                "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": "No tokens found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "43 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": 1
            },
            "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": 59,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.99,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "99 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 99,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 58,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "tsconfig.json"
              ],
              "agent_commit_share": 0.7,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "70 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 70,
                      "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 5",
                "points": 5,
                "status": "partial",
                "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": 263786,
              "source_files_sampled": 210,
              "oversized_source_files": 4
            },
            "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": "4/210 source files over 60KB",
                "points": 54,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 210,
                      "oversized": 4
                    }
                  }
                ],
                "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:@modelzen/feishu-codex-bridge@0.6.10; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-23T11:42:55.415673Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/m/modelzen/feishu-codex-bridge.svg",
  "full_name": "modelzen/feishu-codex-bridge",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Las puntuaciones son señales, no garantías. Reflejan prácticas públicamente visibles en GitHub; no son una auditoría de código ni una garantía de seguridad.

Los datos ausentes se excluyen y los pesos se renormalizan; nunca se puntúan como cero. La metodología es versionada y abierta: métricas v1.13.0, esquema v0.27.0 — metodología completa · wiki de métricas.

Cómo se sitúa un resultado dentro del registro general: estadísticas agregadasnpm.