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

xdfnet / iRelay

Codex ↔ DeepSeek 本机中转服务

SwiftSin licencia detectada★ 0 estrellas⑂ 0 forksdesde jun 2026Ver en GitHub ↗

xdfnet/iRelay tiene un índice de salud de 38 sobre 100, lo que lo sitúa en la banda En riesgo. Su puntuación más alta es Engineering Quality (66/100) y la más baja, Community & Adoption (12/100). Se actualizó por última vez hace 1 día. Una sola persona concentra la mayor parte del trabajo reciente.

38
global / 100
En riesgo

Í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.

38
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

DavidCuenta personal
10 seguidores9 repositorios públicosdesde jul 2020

Este repositorio pertenece a una cuenta personal. Un proyecto con un único propietario conlleva más riesgo de continuidad que uno respaldado por una organización.

Métricas por categoría

Vitalidad

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

64Moderado · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 1 días
4.2/36Cadencia de commits — 6/52 semanas con commits
16.2/18Volumen de commits — 62 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_year62
human_commit_share1
days_since_last_push1
active_weeks_last_year6
Cómo se puntúa
27/27Publica versiones — 1 versiones publicadas
36/36Recencia de las versiones — última versión hace 1 días
12.6/27Cadencia de publicación — cadencia desconocida (una sola versión)
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Datos de entrada utilizados
releases_count1
latest_release_tagv2.2.0
releases_from_tagsno
days_since_latest_release1
mean_days_between_releases

Comunidad y Adopción

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

12Crítico · 18% del índice global
Cómo se puntúa
0/60Estrellas — 0 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
0/22.5Licencia — no se detectó ningún archivo de licencia
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_licenseno
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno

Sostenibilidad y Gobernanza

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

18Crítico · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
0/22.5Distribución de commits — el principal contribuyente firma el 100% de los commits
1.4/13.5Amplitud de contribuyentes — 1 contribuyentes
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Datos de entrada utilizados
bus_factor1
contributors_sampled1
top_contributor_share1
Cómo se puntúa
0/46.8Resolución de issues — sin issues o sin datos
0/38.3Aceptación de PR — 0/1 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs1
Excluidos de la puntuación (sin datos o no aplicable): Resolución de issues. Los pesos restantes se han renormalizado.
Cómo se puntúa
10/30Respaldo de la propiedad — cuenta personal (usuario)
0/20Dominio verificado — no aplicable a cuentas de usuario
7.5/25Alcance del propietario — 10 seguidores de xdfnet
19.3/25Trayectoria — 9 repos públicos, cuenta de ~6 años
Datos de entrada utilizados
followers10
owner_typeUser
is_verified
owner_loginxdfnet
public_repos9
account_age_days2201
Excluidos de la puntuación (sin datos o no aplicable): Dominio verificado. Los pesos restantes se han renormalizado.

Calidad de Ingeniería

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

66Moderado · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 1 flujo(s) de trabajo
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_ci
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.
Cómo se puntúa
30/30README
25/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
10/10Descripción del repositorio
0/10Topics
10/10Wiki
Datos de entrada utilizados
topics
has_wiki
homepage
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?

26Crí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/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
0/2.5Licencia — license file not detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — sin datos
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate2,6
Excluidos de la puntuación (sin datos o no aplicable): ci_tests, packaging. 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.

52Moderado · 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 — 61 de 62 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,984
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 — Swift (tipado estático)
0/10Entorno reproducible
10/10Práctica demostrada con agentes — 47 de los últimos 62 commits con autoría o crédito de agente
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Datos de entrada utilizados
has_nixno
has_tests
lockfiles
has_dockerfileno
typed_language
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0,758
toolchain_manifests
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — Swift (tipado estático)
55/55Tamaños de archivo manejables — 0/14 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageSwift
largest_source_bytes36.857
source_files_sampled14
oversized_source_files0

Datos clave

0estrellas de GitHub
1contribuidores
62commits en los últimos 12 meses
1días desde el último push
1versiones publicadas
1factor bus
0issues abiertas
ecosistemas de paquetes

Advertencias de recopilación de datos

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Más detalle

OpenSSF Scorecard 2.6 / 10
2.6agregado

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-22 07:23 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
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
0Licenselicense file not detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
n/dPackagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
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": [],
      "is_fork": false,
      "size_kb": 2175,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Shell": 2037,
        "Swift": 101262
      },
      "pushed_at": "2026-07-20T16:43:44Z",
      "created_at": "2026-06-14T13:41:27Z",
      "owner_type": "User",
      "updated_at": "2026-07-20T16:43:48Z",
      "description": "Codex ↔ DeepSeek 本机中转服务",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": null,
      "default_branch": "main",
      "license_spdx_raw": null,
      "primary_language": "Swift",
      "significant_languages": [
        "Swift"
      ]
    },
    "owner": {
      "blog": null,
      "name": "David",
      "type": "User",
      "login": "xdfnet",
      "company": null,
      "location": "Beijing.China",
      "followers": 10,
      "avatar_url": "https://avatars.githubusercontent.com/u/68147460?v=4",
      "created_at": "2020-07-11T09:51:56Z",
      "is_verified": null,
      "public_repos": 9,
      "account_age_days": 2201
    },
    "license": {
      "state": "absent",
      "spdx_id": null,
      "raw_spdx": null,
      "file_present": false,
      "scorecard_found": false,
      "profile_has_license": false
    },
    "activity": {
      "releases": [
        {
          "tag": "v2.2.0",
          "kind": "minor",
          "published_at": "2026-07-20T11:18:37Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "e653d5cf8a92cd2c87843d188aae1e8586d9e5da",
          "body": "- 黑色渐变底 + 饱和天蓝 house.fill 符号,居中略偏上\n- 新增 Scripts/gen_icon.swift 生成脚本,便于后续调整\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "更新 App 图标为 house.fill 设计",
          "author_name": "David",
          "author_login": "xdfnet",
          "committed_at": "2026-07-20T16:43:41Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9137aa127764d4a77f1250ce8122bbfb93428976",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to 2.2.0",
          "author_name": "David",
          "author_login": "xdfnet",
          "committed_at": "2026-07-12T12:04:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d3536e53a4b547ca79e39821a7a26478100eb97",
          "body": null,
          "is_bot": false,
          "headline": "fix: App 路径从 Codex.app 改为 ChatGPT.app",
          "author_name": "David",
          "author_login": "xdfnet",
          "committed_at": "2026-07-12T11:58:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cee5149f4406f3b5a5821d253e7feb5a9b47b665",
          "body": "深蓝紫渐变背景 + 白色 r.circle.fill 符号。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: App 图标改为 SF Symbol r.circle.fill",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-07-03T07:35:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9ecee406dda5845899b7816b79f79972f47bf82c",
          "body": "双节点数据流转发图标,深蓝紫渐变底色 + 白色中继符号。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: 重新设计 App 图标",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-07-03T07:33:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "65b37e22654f091af349f383d66dbfb106218dba",
          "body": "Codex CLI 已将 Max 作为 first-class reasoning effort,\niRelay model catalog 同步添加。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: 模型目录新增 Max 推理等级",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-07-03T07:32:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9d00fc086cdf280e026e8458fa7c18459846dc79",
          "body": "- 修复:CodexAppPatcher 原始字符串 s → l 适配新版 Codex 0.142.x\n- 文档:README 新增 Codex 兼容性表格,写明版本支持范围\n- 版本号统一更新到 2.1.12\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump to v2.1.12, 适配新版 Codex asar 变量名",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-27T08:35:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d48bf3af73329d08207f1c6592cfaa1930cbc5aa",
          "body": "每次点开菜单同步查询 /user/balance,实时显示不退缓存\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: 菜单显示 DeepSeek 账户余额",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-25T12:42:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "82b7d1c164bff85473976c9376800334a89fa28e",
          "body": "解决下拉框对齐偏移问题。菜单改为点击时动态构建 NSMenu,\n用完释放,锚点跟随图标。\n\n新增 MenuBarController.swift,删除 MenuBarView.swift。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: 菜单栏从 SwiftUI MenuBarExtra 改为 AppKit NSStatusItem",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-25T12:32:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9a07ce9a125371f2b82497800b4330bf47531988",
          "body": "- supported_reasoning_levels 增加 ultra(智能协作)\n- reasoning_effort 完全透传 DeepSeek,不做额外映射\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: 模型目录新增 Ultra 推理等级,移除多余映射",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-25T12:13:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3382ebe857c77fec8dce685d8c28e5ac28421128",
          "body": "与 Codex 自家模型(gpt-5.5、gpt-5.4-mini)的默认行为对齐\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: DeepSeek 模型默认推理等级改为 medium",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-25T10:40:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d3b48c4ed053add313df3306cab83b78db44b99e",
          "body": "responsesToChatPayload 直接取 body['model'] 原始值,\n未经过 resolveModel 转换,导致 gpt-5.4-mini 等非\nDeepSeek 模型发往上游时被拒(400)。\n\n在 responsesToChatPayload 中用 Self.resolveModel()\n替换裸读 body['model'],与 handleResponses 的日志\n层对齐。\n\nbump v2.1.7\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: 模型重写未生效——payload 中 model 仍用原始名",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-25T10:23:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1bc38fdf2f06677178be15391929c9031ec6f677",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: 推理模式改为开启/关闭推理,菜单语义统一",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-25T09:40:58Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b302d777049209b57aceb92b5d0dd475ef55f10f",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: 集成→代理,与补丁解耦后语义更准确",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-25T09:36:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "920b5f4f75c5a5e1d2cf137a63c415ea2a04483b",
          "body": "- 集成开关不再自动打补丁,各自独立控制\n- 新增「开启补丁/关闭补丁」菜单项(含状态检测)\n- 操作前检测 App 管理权限,未授权弹窗引导\n- 更新 README 反映新菜单结构和操作流程\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: 补丁与集成完全解耦,独立菜单开关+权限前置检查",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-25T09:35:21Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "24f70d5294a5425c5affaec9e19c16c8dd5350b1",
          "body": "- RelayState 新增 activeRequestCount 追踪活跃请求数\n- RelayHandler 添加 onRequestActive/onRequestInactive 回调\n- 菜单栏图标用 SF Symbol 交替(circle.fill ⇄ circle)实现闪烁\n- 禁用状态使用 slash.circle.fill,无数据流时固定 circle.fill\n- 停止服务时自动归零请求计数\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: 菜单栏图标在有数据流时闪烁",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-24T06:36:24Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f98ec100092f2e5495835bbcd130acfc581bd781",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to 2.1.4",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T07:02:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7d36ec7cf6fe61ea41e525af9d8eb3e787b99b6f",
          "body": "- 移除模型切换相关描述\n- 使用步骤简化(开启集成 → 自动完成)\n- 架构图更新为当前菜单结构\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: 更新 README 反映菜单精简",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T07:02:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "76e3bf2cb8dcf92c4ef7ac2b095bc016b7f0b20c",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 2.1.3",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T07:00:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "34bfac77cd0eb931b0f9fbccafb282e9109885e6",
          "body": "ensurePatched() 先查 asar 状态:\n  已打补丁 → return true,不动备份\n  未打 → 删旧备份 → 备份原始 asar → 打补丁\n\n确保 restoreFromBackup() 还原的永远是原始版本。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: 仅首次打补丁时创建备份,已打好不动备份",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T06:50:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "24d5c867c72cb10690c72318663f4335ab38a3e1",
          "body": "ensurePatched() 先备份 app.asar → app.asar.bak,再打补丁。\n备份留在磁盘上:\n- enable 写配置失败 → restoreFromBackup() 还原\n- disable → restoreFromBackup() 还原 + 删备份 + 清配置\n\n备份文件不依赖内存,进程崩溃也能恢复。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: asar 回滚改为文件备份方式",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T06:48:48Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "149f25be0372323708cb11d8eb75d11bb390368e",
          "body": "disable():\n  ① 还原 asar(patched → original,反向等长替换)\n  ② 清 config.toml\n  ③ 删 model catalog\n\n每一步失败都中止,不回退上一步(但已做的事不影响下一轮)。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: 关闭集成时还原 asar,不留痕迹",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T06:46:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b46347999482cf94b261a29069c99762985fbb60",
          "body": "enable():\n  ① 缓存原始 asar\n  ② 打补丁 → 失败 → ❌(没改任何东西)\n  ③ 写配置 → 失败 → 🔄 写回原始 asar → ❌\n  ④ 成功 ✅\n\n回滚需要先读取 asar 权限,和打补丁一样——如果回滚写入也失败,\n至少比现在半残状态好(原版 asar 已有补丁 vs 配置没写)。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: 启用集成改为事务式,失败自动回滚",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T06:43:24Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "58e3cbe66335abb6e9a4ba7dda488af333a1236c",
          "body": "Button(\"中文\") 和 Text(\"中文\") 会被 Swift 6.3 -O\n当作 LocalizedStringKey 优化掉。改用 Text(verbatim:)\n显式指定 String 类型,绕过优化器。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: release 编译字符串被优化掉的问题",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T06:37:42Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "37ea0464125402921174d02c6c9b2b113d8f45e7",
          "body": "CodexAppPatcher 只剩 55 行:\n- applyPatch() 读→替换→写回\n- 失败弹窗引导授权\n\n没有守护线程、没有备份、没有探针写入、没有权限状态缓存。\n用户开启集成时检查权限,失败弹窗,成功后不管。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: 彻底精简,删除 guard 轮询",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T06:33:24Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3d3a426d1d49e9120247ce371f79cd7795ccfad9",
          "body": "- 去掉备份/还原/探针写入等复杂逻辑\n- applyPatch() 只做一件事:读→替换→写→返回成败\n- 弹窗仅启动时用户主动开启集成时触发\n- init() 只启动服务器,不碰补丁\n- guard 60s 静默重试,处理 Codex 升级场景\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: 精简 CodexAppPatcher + 启动不做多余事",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T06:32:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8d4820fb3be627df1d98ee7dc540c421ed7cdfb0",
          "body": "菜单精简为:\n  开启/关闭 Codex 集成\n  ─────\n  推理模式 ✓\n  ─────\n  设置密钥\n  打开日志\n  ─────\n  退出\n\ntoggleCodex() 自动设 model = deepseek-v4-pro\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: 去掉模型选择菜单,开启集成默认 pro",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T06:17:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0c31311c6eabf7dcc13b448fb214514fe5cfd7a1",
          "body": "Image(systemName:) 在 MenuBarExtra 下可能不渲染,\n改用 Text(\"✓\") 确保始终可见\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: 菜单对勾改为文本符号",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T06:11:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3e1d19917da4240dd461b62d064c00d92bd45933",
          "body": "RelayState.init() 新增 syncCodexConfig() 调用,\n确保重启时补丁状态被检查,权限不通则阻断引导。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: App 重启后自动触发补丁检查",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:55:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6c823ce4338051eb07f67efcaa8671b32e95cdb0",
          "body": "ensurePatched() 遇到 EPERM → 阻塞主线程循环弹窗:\n  -「打开系统设置」→ 跳转 → 自动重试补丁\n  -「退出 iRelay」→ 终止 App\n  不授权别想用。\n\n启动成功后 guard 只 stat mtime + 重打补丁,不再涉及权限。\napplyPatch() 不再区分 notify,永远静默。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: 启动时权限阻断,启动后不关心权限",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:52:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2412ce1ba10b7072ec7ce9f41e9abcb6a3c9d27c",
          "body": "applyPatch(notify:) 是唯一写 asar 的地方:\n- notify=true(首次):失败弹窗引导\n- notify=false(guard):静默重试,不下轮\n\n后台线程 stat → mtime 变了再走 applyPatch。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: 精简补丁逻辑,统一核心方法",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:48:37Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4d080d0b31479c3c0895cdcf3633804077f08dbc",
          "body": "每 60 秒只 stat 一次 asar mtime(不读内容),\nmtime 没变(Codex 没升级)直接跳过,零磁盘 IO。\nmtime 变了才读 155MB asar 验补丁+重打。\n权限探测内联到确保补丁的写入步骤,不再单独 probe 写回。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf: guard 循环改为 stat 驱动",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:46:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "97a5c719e8cdea541a109dd1f241fb1661b85b38",
          "body": "每 10 秒依次做两件事,各自独立互不影响:\n\n1. checkPermission() — 轻量写入探测 App 管理权限\n   缺权限时弹 NSAlert(防重复),引导用户打开系统设置\n   点「打开系统设置」跳转隐私→App 管理面板\n\n2. ensurePatchIntact() — 读 asar 验证补丁完整性\n   补丁丢了(Codex 升级)→ 自动重打\n\n与 iVox 的权限轮询模式一致。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: guard 循环改为 10 秒双检查",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:38:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6aa2a3acb81d858df076109bb5c7540e80a38e39",
          "body": "补丁写入被系统拒绝时(EPERM/EACCES)弹出 NSAlert:\n- 标题:「需要 App 管理权限」\n- 正文:引导前往 系统设置 → 隐私与安全性 → App 管理\n- 按钮:「打开系统设置」→ 跳转对应面板\n- 按钮:「稍后」→ 关闭,guard 后台继续等\n\n仅初始 ensurePatched() 弹一次,guard 循环静默重试。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: 权限不足时弹窗引导用户",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:34:44Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d31e98a6cdcd37b9e4b2886d953ce8a2cf1e77ac",
          "body": "启用:打补丁→写配置,写配置失败时还原 asar\n关闭:还原 asar→清配置,清配置失败时重打补丁\n任一失败均回滚到操作前状态,不产生半残状态\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: 启用/关闭全链路回滚",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:31:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a2d30533fc0dd06761071f8e2aaab2c50a2d676f",
          "body": "启用:先打补丁(权限检查)→ 成功后才写配置 → 全做完\n关闭:先还原补丁(权限检查)→ 成功后才清配置 → 全做完\n\n任一前置步骤失败则中止,不产生半应用状态。\nguard 线程生命周期由 enable/disable 显式管理。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: 启用/关闭流程改为事务式",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:29:58Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3a2e6e146fd9daaa79d5befc169f8b077ebd2ab6",
          "body": "ensurePatched() 无论成败都启动 guard 线程,每 60 秒检查\n一次 asar 补丁完整性。Codex 升级后 asar 被还原时,guard\n能在下一轮检测到并自动重打补丁。\n\n同时替代了之前的权限轮询逻辑(职责合并)。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: 后台守护线程持续验证 Codex 补丁",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:24:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f767ef6d51e72644ee139f76cfde81875df67856",
          "body": "仿 iVox 模式,Codex App 补丁写入失败时(EPERM/EACCES),\n每 5 秒轮询重试,权限就绪后自动打补丁。\n解决 Codex 每次升级后补丁失效的问题。\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: 添加 App 管理权限轮询机制",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:21:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d0ce2accde21eec4a3b164c8123660710e161036",
          "body": "ad-hoc 签名下 entitlements 不生效,删掉保持简洁\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: 移除无实际约束的 entitlements",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:14:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d7def4152b04efe3df56ed7660aecc590768dbfd",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: 签名简化为纯 ad-hoc",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:12:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ac8d9f6b319de741018a36560afd5f043e681677",
          "body": "- 新增 Resources/iRelay.entitlements,显式声明 network.server/client、\n  files.user-selected 权限,适配 Hardened Runtime\n- build.sh:自动查找有效签名证书(不再硬编码已吊销的证书)、\n  启用 Hardened Runtime(--options runtime)、使用 entitlements 文件签名\n- Info.plist 版本号同步至 2.1.3\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: 完善权限配置与签名流程",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:11:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "86799df796e57998848de6ec66d1dfb52bd2f2a2",
          "body": "为 DeepSeek 编写更贴合代码助手场景的系统指令,涵盖\n1M 上下文窗口、推理等级、工具调用等关键能力描述\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: 升级 model catalog base_instructions",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:09:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7d65c2510a69d85849bacc79bbe827e667b1e961",
          "body": "- model catalog 新增 auto_compact_token_limit / web_search_tool_type /\n  xhigh 推理等级 / supports_reasoning_summaries / support_verbosity\n- app.asar 补丁重打(Codex v26.616 验证通过)\n- 修复 Swift 6.3 编译器访问控制变更导致的构建失败\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: 适配 Codex 最新升级",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-21T05:08:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c303ddb2438bbc452dcaf312dd5eb3dab0ddf6a6",
          "body": "Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: 开发证书吊销时自动降级 ad-hoc 签名",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-19T14:08:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7a9e3a4ccd9431db193a81c16f907e99f1f42281",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: 菜单栏按钮文案调整 '密钥设置...' → '设置密钥'",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T09:41:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1a210ee993641e49628d718152c160273eb1417a",
          "body": "- Codex 集成开关移至菜单顶部\n- 从 Git 追踪移除 iRelay.app(已在 .gitignore)",
          "is_bot": false,
          "headline": "chore: bump version to 2.1.2",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T07:11:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b4470f1d74a5b55050805eeace1d93a25e9e4856",
          "body": "- 菜单重构:模型平铺、推理模式改切换、密钥移出一级\n- 新增 toggleCodex():一键开关 Codex 集成\n- build.sh:改用开发者证书签名,自动安装+清除隔离属性",
          "is_bot": false,
          "headline": "chore: bump version to 2.1.1",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T07:06:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "acecbeda53e0e96636a17662b67d28f9d19c8f88",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to 2.1.0",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:53:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "472e7f45fc9e2eecfc50b1d1bd7310e08a2b9c1d",
          "body": "- 更新 README.md:移除多提供商/端口配置,模型切换/思考/Chat 透传\n- 更新 ARCHITECTURE.md 到 v2.1.0:纯 DeepSeek + 固定端口 + Chat 透传\n- 新增 Doc/API.md:完整对外 API 文档(4 个端点/请求/响应/流式格式)\n- Logger: 消息日志显示 (N chars): preview\n- MenuBarView: 文字精简",
          "is_bot": false,
          "headline": "doc: 更新文档并补充 API 文档",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:51:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b438681e3faf6f09ec9f98e6e2cf5086eaba7f0e",
          "body": null,
          "is_bot": false,
          "headline": "chore: 移除端口配置,固定 8787",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:40:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a5d104e2afeec61c4d631a57fb8a12c9f7124ca4",
          "body": "删除 ProviderStore,RelayState 恢复直接持有 apiKey/model/thinking\nCodexConfigManager 恢复 enable(model:port:)\nMenuBarView/iRelayApp 去掉提供商管理,仅保留模型/模式/端口/Key\nsetThinking 通过更新 handler.provider.thinkingMode 生效",
          "is_bot": false,
          "headline": "refactor: 移除多提供商,回到纯 DeepSeek",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:38:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "17215e52e03e6b91bae0ac30e9960cd2ef26ccd8",
          "body": null,
          "is_bot": false,
          "headline": "chore: 移除 handleChatCompletions 未使用变量",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:29:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b9f40e3972d1af98f9a8b98ef3383ea97310e92a",
          "body": "- 流式:标准 data: 格式 SSE 逐帧透传\n- 非流式:JSON 原样透传\n- HTTPServer 新增 sendSSEData 方法发送裸 data: 行\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: 添加 POST /v1/chat/completions 透传接口",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:27:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "adaab9c0b883d3c0c98656840a3739115b1e1529",
          "body": null,
          "is_bot": false,
          "headline": "doc: 更新 ARCHITECTURE.md 到 v2.0.0 — 多提供商 / 协议矩阵 / 测试覆盖 / 适配历史",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:20:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "99e9596d75f58be13b54fa9110b78ac70370896c",
          "body": null,
          "is_bot": false,
          "headline": "chore: add iRelay.zip to .gitignore",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:16:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7a6bd41262ad7b015f4e6921e2e42282ec4f4138",
          "body": null,
          "is_bot": false,
          "headline": "chore: remove iRelay.zip from tracking",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:16:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3ee5864ad0bfaf3c373fb18cf6bfe884b1499ba7",
          "body": "- usage 补 input_tokens_details(cached_tokens) + output_tokens_details(reasoning_tokens)\n- 流开始发 response.metadata SSE 事件(含 x-codex-turn-state / openai-model)\n- reasoning.effort 透传到 Chat API 的 reasoning_effort 字段\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "补: 三个协议补丁 — usage 明细 / response.metadata / reasoning.effort",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:16:37Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "398483753ec7ac7525a6de13ca03f2d96e090663",
          "body": null,
          "is_bot": false,
          "headline": "remove accidental iRelay.zip from tracking",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:13:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ae7f3620f4886d95fc84fbcb49ac4c94ac5c2e0d",
          "body": "- 拆 iRelayCore library target,iRelay 可执行 target 依赖 iRelayCore\n- 新增 iRelayTests test target\n- 26 个测试覆盖:responsesToChatPayload、chatCompletionToResponse、\n  collectFunctionCalls(验证修过的 bug)、parseInput、contentToText、\n  convertTools、ensureToolAfterAssistant、ProviderConfig 配置\n- 修复 iRelayApp.swift 未使用变量 warning\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test: 拆 target 结构 + 26 个协议转换单元测试",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:13:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9b349a488ddfd06e478dea46b27b1632987768ad",
          "body": "- 新增 ProviderConfig 数据模型,支持任意 OpenAI Chat API 兼容提供商\n- 新增 ProviderStore 多提供商持久化 + v1 自动迁移\n- 重命名 DeepSeekClient → ChatClient,通用 Chat API 客户端\n- RelayHandler 注入 ProviderConfig:thinking/reasoning 字段动态化\n- 添加 end_turn output_item,补全 Responses API 协议\n- 端口可配置(菜单栏 UI)\n- 提供商切换 UI + 管理窗口\n- README / ARCHITECTURE.md 同步更新,版本号 2.0.0\n\n保留 v1 向后兼容:旧 UserDefaults 键在首次启动时自动迁移\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v2.0.0: 多提供商通用化改造",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T06:03:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8015478217594b59aac5fc9292c73f7e6a9f31c0",
          "body": "Responses API 的 function_call item 中 name/arguments 在顶层,\n之前按 Chat API 嵌套 function.name 读导致工具名传空。\n\n同步更新 ARCHITECTURE.md,补充协议映射表、SSE 事件对比、适配历史。\n\nCo-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: 修复 collectFunctionCalls 字段路径 — 读 item.name 而非 item.function.name",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-15T05:53:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4efc1610a6e5627fbfc9caaa2d6976b509cb7d4f",
          "body": null,
          "is_bot": false,
          "headline": "init: iRelay — Codex ↔ DeepSeek 本机中转服务,macOS 菜单栏原生 App",
          "author_name": "David",
          "author_login": null,
          "committed_at": "2026-06-14T13:43:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 1,
      "commits_last_year": 62,
      "latest_release_at": "2026-07-20T11:18:37Z",
      "latest_release_tag": "v2.2.0",
      "releases_from_tags": false,
      "days_since_last_push": 1,
      "active_weeks_last_year": 6,
      "days_since_latest_release": 1,
      "mean_days_between_releases": null
    },
    "community": {
      "has_readme": true,
      "has_license": false,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 28,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 36857,
      "source_files_sampled": 14,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [],
      "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": [],
      "dependencies": [],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 0,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 1
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "xdfnet",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/68147460?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "build.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 0,
            "reason": "license file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "e653d5cf8a92cd2c87843d188aae1e8586d9e5da",
        "ran_at": "2026-07-22T07:23:46Z",
        "aggregate_score": 2.6,
        "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-20T16:44:37Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": null,
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/xdfnet/iRelay",
    "host": "github.com",
    "name": "iRelay",
    "owner": "xdfnet"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 38,
      "inputs": {
        "security": 26,
        "vitality": 64,
        "community": 12,
        "governance": 18,
        "engineering": 66
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "moderate",
        "name": "Vitality",
        "value": 64,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 56,
            "inputs": {
              "commits_last_year": 62,
              "human_commit_share": 1,
              "days_since_last_push": 1,
              "active_weeks_last_year": 6
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 1 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 1
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "6/52 weeks with commits",
                "points": 4.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "62 commits in the last year",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 62
                    }
                  }
                ],
                "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": "good",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 76,
            "inputs": {
              "releases_count": 1,
              "latest_release_tag": "v2.2.0",
              "releases_from_tags": false,
              "days_since_latest_release": 1,
              "mean_days_between_releases": null
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "1 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 1 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 1
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "cadence unknown (single release)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "release_cadence_unknown",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 12,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "critical",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 25,
            "inputs": {
              "has_readme": true,
              "has_license": false,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "no license file detected",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "license_absent",
                    "params": {}
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "critical",
        "name": "Sustainability & Governance",
        "value": 18,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "merged_prs": 0,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 1
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "0/1 decided PRs merged",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 0,
                      "decided": 1
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 46,
            "inputs": {
              "followers": 10,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "xdfnet",
              "public_repos": 9,
              "account_age_days": 2201
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "10 followers of xdfnet",
                "points": 7.5,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 10,
                      "login": "xdfnet"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "9 public repos, account ~6 yr old",
                "points": 19.3,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 9
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 6
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 66,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "1 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "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": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "critical",
        "name": "Security",
        "value": 26,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Packaging. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "packaging"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 26,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 2.6
            },
            "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 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow 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 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 2
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 52,
        "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.984,
              "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": "61 of 62 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 61,
                      "sampled": 62
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 43,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.758,
              "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": "Swift (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Swift"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "47 of the last 62 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 47,
                      "sampled": 62
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "Swift",
              "largest_source_bytes": 36857,
              "source_files_sampled": 14,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Swift (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Swift"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/14 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 14,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-22T07:23:50.998871Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/x/xdfnet/iRelay.svg",
  "full_name": "xdfnet/iRelay",
  "license_state": "absent",
  "license_spdx": null
}

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.26.0 — metodología completa · wiki de métricas.

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