Registro público
Informe de salud del softwareesquema 0.31.0 · métricas 2.5.0 · 2026-08-05 20:54 UTC

n1byn1kt / apitap

CLI, MCP server, and npm library that turns any website into an API — no docs, no SDK, no browser.

TypeScriptApache-2.0★ 123 estrellas⑂ 9 forksdesde feb 2026Ver en GitHub ↗
TipoBibliotecaHerramienta de línea de comandosServidor MCPcómo se determina

n1byn1kt/apitap tiene un índice de salud de 75 sobre 100, lo que lo sitúa en la banda Bueno. Su puntuación más alta es Engineering Quality (81/100) y la más baja, Sustainability & Governance (48/100). Se actualizó por última vez hace 10 días. Una sola persona concentra la mayor parte del trabajo reciente.

75
global / 100
Bueno

Índice de salud del software

Las métricas se agrupan en categorías ponderadas sobre una escala estandarizada de 1 a 100. El resultado global parte de su media ponderada, calibrada contra la distribución del registro público para que las bandas tengan significado percentil; cuando la evidencia pública activa la Política de Jurisdicciones de Alto Riesgo, la calificación se ajusta y recibe un límite «En riesgo» de 34.

75
Excepcional93-100El nivel más alto del registro (≈ el 5% superior); cumple prácticamente todos los criterios evaluados
Excelente80-92Sólido en todos los frentes; carencias menores
Bueno65-79Saludable; carencias limitadas y manejables
Moderado50-64Aceptable con carencias notables; se recomienda revisión
Débil35-49Debilidades sustanciales en varias áreas
En riesgo20-34Debilidades significativas; su adopción exige cautela
Crítico1-19Problemas 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.

El resultado global ponderado 65 se calibra a 75 en la escala publicada del índice (calibración del registro 2026-08-02).

Titularidad

n1byn1ktCuenta personal
0 seguidores2 repositorios públicosdesde nov 2025

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.

Ecosistemas de paquetes

Métricas por categoría

Vitalidad

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

79Bueno · 21% del índice global
Cómo se puntúa
28.8/36Recencia de push — último push hace 10 días
8.3/36Cadencia de commits — 12/52 semanas con commits
18/18Volumen de commits — 374 commits en el último año
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 9 issue activity found in the last 90 days -- score normalized to 10
Datos de entrada utilizados
commits_last_year374
human_commit_share1
days_since_last_push10
active_weeks_last_year12
Cómo se puntúa
27/27Publica versiones — 64 versiones publicadas
36/36Recencia de las versiones — última versión hace 10 días
27/27Cadencia de publicación — una versión cada ~0,7 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count64
latest_release_tagv2.2.3
releases_from_tagsno
days_since_latest_release10
mean_days_between_releases0,7
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Signed-Releases. Los pesos restantes se han renormalizado.

Comunidad y Adopción

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

60Moderado · 17% del índice global
Cómo se puntúa
33.8/60Estrellas — 123 estrellas
7.5/25Forks — 9 forks
0/15Observadores — 1 observadores
Datos de entrada utilizados
forks9
stars123
watchers1
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (Apache-2.0)
18/18Guía CONTRIBUTING
13.5/13.5Código de conducta
0/7.2Plantilla de issues
0/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
readme_badges3
has_contributing
has_issue_templateno
has_code_of_conduct
readme_badge_servicesshields.io
has_pull_request_templateno
Cómo se puntúa
44.1/80Descargas mensuales — 2030 descargas/mes en npm
0/20Dependientes en el registro — no lo informa este ecosistema
Datos de entrada utilizados
packages@apitap/core
dependents
ecosystemsnpm
total_downloads
monthly_downloads2030
Excluidos de la puntuación (sin datos o no aplicable): Dependientes en el registro. Los pesos restantes se han renormalizado.

Sostenibilidad y Gobernanza

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

48Débil · 23% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
2.3/22.5Distribución de commits — el principal contribuyente firma el 90% de los commits
2.7/13.5Amplitud de contribuyentes — 2 contribuyentes
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Datos de entrada utilizados
bus_factor1
contributors_sampled2
top_contributor_share0,897
Cómo se puntúa
40.2/42Resolución de issues — 96% de issues cerradas
27.9/30Aceptación de PR — 52/56 PR decididos fusionados
0/13Newcomer PR acceptance — ningún PR de un contribuyente primerizo decidido en 30 d
0/15OpenSSF Scorecard: Code-Review — Found 0/10 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs52
open_issues1
closed_issues22
prs_merged_7d0
prs_decided_7d0
prs_merged_30d15
prs_decided_30d16
issue_closed_ratio0,957
closed_unmerged_prs4
first_time_authors_30d0
first_time_prs_merged_30d0
first_time_prs_decided_30d0
Excluidos de la puntuación (sin datos o no aplicable): newcomer_pr_acceptance. 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
0/25Alcance del propietario — 0 seguidores de n1byn1kt
4.9/25Trayectoria — 2 repos públicos, cuenta de ~0 años
Datos de entrada utilizados
followers0
owner_typeUser
is_verified
owner_loginn1byn1kt
public_repos2
account_age_days269
Excluidos de la puntuación (sin datos o no aplicable): Dominio verificado. Los pesos restantes se han renormalizado.
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en npm
35/35Recencia de publicación — última publicación hace 11 días
20/20Historial de versiones — 66 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packages@apitap/core
ecosystemsnpm
any_deprecatedno
min_days_since_publish11

Calidad de Ingeniería

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

81Excelente · 19% 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
20/20OpenSSF Scorecard: CI-Tests — 5 out of 5 merged PRs checked by a CI test -- score normalized to 10
Datos de entrada utilizados
has_ci
has_tests
has_editorconfigno
has_linter_configno
has_precommit_configno

Documentación

100Excepcional
Cómo se puntúa
30/30README
25/25Directorio de documentación
15/15Sitio de documentación / página del proyecto — https://www.apitap.io
10/10Descripción del repositorio
10/10Topics — 8 topics
10/10Wiki
Datos de entrada utilizados
topicsai-agent, api, browser-automation, mcp, mcp-server, playwright, web-scraping, skill-file
has_wiki
homepagehttps://www.apitap.io
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?

59Moderado · 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
2.5/2.5CI-Tests — 5 out of 5 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/10 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
2.5/2.5Licencia — license file detected
7.5/7.5Maintained — 30 commit(s) and 9 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — sin datos
5/5Pinned-Dependencies — all dependencies are pinned
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
5/5Security-Policy — security policy file detected
0/7.5Signed-Releases — sin datos
7.5/7.5Token-Permissions — GitHub workflow tokens follow principle of least privilege
0/7.5Vulnerabilities — 40 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate5,1
Excluidos de la puntuación (sin datos o no aplicable): packaging, signed_releases. Los pesos restantes se han renormalizado.
Cómo se puntúa
35/35Dependencias directas libres de avisos conocidos — ninguna dependencia directa tiene un aviso conocido
14.4/25Dependencias indirectas libres de avisos conocidos — 1 afectados: hono 4.12.33 (moderate 5.3)
40/40Sin avisos pendientes — ningún aviso lleva público más de 90 días
Datos de entrada utilizados
sourceosv
advisories1
affected_packages1
assessed_packages100
unassessed_packages0
affected_by_severitymoderate 1
direct_affected_packages0
Se cotejó el cierre de dependencias en tiempo de ejecución de npm:@apitap/core@2.2.2 —lo que arrastra la instalación del paquete publicado—: 100 paquetes. No se analiza la alcanzabilidad.

Preparación para IA

¿Hasta qué punto está el repositorio preparado para desarrollarse y mantenerse con agentes de codificación de IA? Tiene un peso deliberadamente pequeño (4%): las herramientas para agentes son una señal real de mantenimiento, pero un repositorio sin ninguna puede alcanzar igualmente 100/100.

69Bueno · 4% del índice global
Cómo se puntúa
45/45Instrucciones para agentes — .github/copilot-instructions.md, CLAUDE.md
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 90 de 100 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,9
agent_instruction_files.github/copilot-instructions.md, CLAUDE.md
agent_instruction_max_bytes6841
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 — extension/tsconfig.json, tsconfig.json
10/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 45 de los últimos 100 commits con autoría o crédito de agente
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
10/10OpenSSF Scorecard: Pinned-Dependencies — all dependencies are pinned
Datos de entrada utilizados
has_nixno
has_tests
lockfilespackage-lock.json
has_dockerfileno
typed_language
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configsextension/tsconfig.json, tsconfig.json
agent_commit_share0,45
toolchain_manifests
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — TypeScript (tipado estático)
54.8/55Tamaños de archivo manejables — 1/285 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageTypeScript
largest_source_bytes101.477
source_files_sampled285
oversized_source_files1
Cómo se puntúa
0/40Esquema de API (OpenAPI/GraphQL/proto)
20/20Servidor MCP
0/40Ejemplos ejecutables
Datos de entrada utilizados
example_dirs
has_mcp_signal
api_schema_files

Datos clave

123estrellas de GitHub
2contribuidores
374commits en los últimos 12 meses
10días desde el último push
64versiones publicadas
1factor bus
1issues abiertas
npmecosistemas de paquetes

Advertencias de recopilación de datos

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • npm package 'extension' points at a different repository (https://github.com/extension-js/extension.js); excluded from ecosystem scoring
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Más detalle

Historial de estrellas y forks 0 ★ / 9 ⇿
0Estrellas
9Forks
55Versiones

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

035810922026-022026-052026-07
Mayor 1Menor 15Parche 39
OpenSSF Scorecard 5.1 / 10
5.1agregado

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-08-05 20:54 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests5 out of 5 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/10 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
10Licenselicense file detected
10Maintained30 commit(s) and 9 issue activity found in the last 90 days -- score normalized to 10
n/dPackagingpackaging workflow not detected
10Pinned-Dependenciesall dependencies are pinned
0SASTSAST tool is not run on all commits -- score normalized to 0
10Security-Policysecurity policy file detected
n/dSigned-Releasesno releases found
10Token-PermissionsGitHub workflow tokens follow principle of least privilege
0Vulnerabilities40 existing vulnerabilities detected
Dependencias directas 4
RegistroPaqueteRestricción de versiónManifiesto
npm@modelcontextprotocol/sdk^1.26.0package.json
npmjs-yaml^4.1.1package.json
npmplaywright^1.58.1package.json
npmzod^4.3.6package.json
Todas las dependencias no recopilado

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

Avisos de dependencias 1

Instalar npm:@apitap/core@2.2.2 arrastra 100 paquetes, directos y transitivos: 1 tienen avisos conocidos, de los cuales 0 son dependencias directas.

PaqueteVersiónRelaciónGravedadAvisosCorregido en
hono4.12.33indirectamoderada14.12.34

Un aviso significa que la versión registrada en el grafo de dependencias cae dentro del rango afectado de un aviso. No se analiza la alcanzabilidad, y el grafo incluye fijaciones de desarrollo y prueba: un hallazgo puede referirse al utillaje y no al software distribuido.

Informe JSON sin procesar legible por máquina
{
  "data": {
    "icon": {
      "bytes": 14295,
      "width": 192,
      "height": 192,
      "rejected": [],
      "collected": true,
      "media_type": "image/png",
      "source_url": "https://www.apitap.io/logo-192.png",
      "source_type": "homepage",
      "content_hash": "9d49782861061641a05b4973061e640e21fc73c503aed3db2ebf8001c274d65b",
      "candidates_considered": 1
    },
    "repo": {
      "topics": [
        "ai-agent",
        "api",
        "browser-automation",
        "mcp",
        "mcp-server",
        "playwright",
        "web-scraping",
        "skill-file"
      ],
      "is_fork": false,
      "size_kb": 14037,
      "has_wiki": true,
      "homepage": "https://www.apitap.io",
      "languages": {
        "CSS": 6456,
        "HTML": 3584,
        "Shell": 2734,
        "JavaScript": 146323,
        "TypeScript": 1755770
      },
      "pushed_at": "2026-07-25T22:59:08Z",
      "created_at": "2026-02-14T16:20:58Z",
      "owner_type": "User",
      "updated_at": "2026-08-05T14:39:45Z",
      "description": "CLI, MCP server, and npm library that turns any website into an API — no docs, no SDK, no browser.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "main",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "User",
      "login": "n1byn1kt",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/242883047?v=4",
      "created_at": "2025-11-09T02:54:07Z",
      "is_verified": null,
      "public_repos": 2,
      "account_age_days": 269
    },
    "license": {
      "state": "standard",
      "spdx_id": "Apache-2.0",
      "raw_spdx": "Apache-2.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v2.2.3",
          "kind": "patch",
          "published_at": "2026-07-25T22:59:20Z"
        },
        {
          "tag": "v2.2.2",
          "kind": "patch",
          "published_at": "2026-07-25T16:02:56Z"
        },
        {
          "tag": "v2.2.1",
          "kind": "patch",
          "published_at": "2026-07-24T23:58:35Z"
        },
        {
          "tag": "v2.2.0",
          "kind": "minor",
          "published_at": "2026-07-20T04:03:41Z"
        },
        {
          "tag": "v2.1.1",
          "kind": "patch",
          "published_at": "2026-07-19T21:49:12Z"
        },
        {
          "tag": "v2.1.0",
          "kind": "minor",
          "published_at": "2026-07-19T21:07:57Z"
        },
        {
          "tag": "v2.0.1",
          "kind": "patch",
          "published_at": "2026-07-19T19:39:51Z"
        },
        {
          "tag": "v2.0.0",
          "kind": "major",
          "published_at": "2026-07-19T18:47:14Z"
        },
        {
          "tag": "v1.13.0",
          "kind": "minor",
          "published_at": "2026-07-19T16:26:58Z"
        },
        {
          "tag": "v1.12.2",
          "kind": "patch",
          "published_at": "2026-07-19T15:52:05Z"
        },
        {
          "tag": "v1.12.1",
          "kind": "patch",
          "published_at": "2026-05-29T02:29:16Z"
        },
        {
          "tag": "v1.12.0",
          "kind": "minor",
          "published_at": "2026-05-29T01:41:13Z"
        },
        {
          "tag": "v1.11.0",
          "kind": "minor",
          "published_at": "2026-04-08T22:44:27Z"
        },
        {
          "tag": "v1.10.2",
          "kind": "patch",
          "published_at": "2026-04-03T17:12:24Z"
        },
        {
          "tag": "v1.10.1",
          "kind": "patch",
          "published_at": "2026-04-02T13:27:43Z"
        },
        {
          "tag": "v1.10.0",
          "kind": "minor",
          "published_at": "2026-03-29T20:02:50Z"
        },
        {
          "tag": "v1.9.4",
          "kind": "patch",
          "published_at": "2026-03-22T04:09:30Z"
        },
        {
          "tag": "v1.9.3",
          "kind": "patch",
          "published_at": "2026-03-22T04:00:10Z"
        },
        {
          "tag": "v1.9.2",
          "kind": "patch",
          "published_at": "2026-03-22T03:43:58Z"
        },
        {
          "tag": "v1.9.1",
          "kind": "patch",
          "published_at": "2026-03-22T03:41:36Z"
        },
        {
          "tag": "v1.9.0",
          "kind": "minor",
          "published_at": "2026-03-22T03:24:54Z"
        },
        {
          "tag": "v1.8.2",
          "kind": "patch",
          "published_at": "2026-03-22T02:56:36Z"
        },
        {
          "tag": "v1.8.1",
          "kind": "patch",
          "published_at": "2026-03-22T02:29:47Z"
        },
        {
          "tag": "v1.8.0",
          "kind": "minor",
          "published_at": "2026-03-22T01:13:14Z"
        },
        {
          "tag": "v1.7.1",
          "kind": "patch",
          "published_at": "2026-03-21T20:44:48Z"
        },
        {
          "tag": "v1.7.0",
          "kind": "minor",
          "published_at": "2026-03-21T20:32:40Z"
        },
        {
          "tag": "v1.6.4",
          "kind": "patch",
          "published_at": "2026-03-21T03:59:40Z"
        },
        {
          "tag": "v1.6.3",
          "kind": "patch",
          "published_at": "2026-03-21T03:47:19Z"
        },
        {
          "tag": "v1.6.2",
          "kind": "patch",
          "published_at": "2026-03-21T03:16:12Z"
        },
        {
          "tag": "v1.6.1",
          "kind": "patch",
          "published_at": "2026-03-20T15:00:20Z"
        },
        {
          "tag": "v1.6.0",
          "kind": "minor",
          "published_at": "2026-03-20T13:52:25Z"
        },
        {
          "tag": "v1.5.4",
          "kind": "patch",
          "published_at": "2026-03-18T23:12:46Z"
        },
        {
          "tag": "v1.5.3",
          "kind": "patch",
          "published_at": "2026-03-09T03:10:33Z"
        },
        {
          "tag": "v1.5.2",
          "kind": "patch",
          "published_at": "2026-03-09T00:51:30Z"
        },
        {
          "tag": "v1.5.1",
          "kind": "patch",
          "published_at": "2026-03-09T00:13:41Z"
        },
        {
          "tag": "v1.5.0",
          "kind": "minor",
          "published_at": "2026-03-08T20:23:51Z"
        },
        {
          "tag": "v1.4.3",
          "kind": "patch",
          "published_at": "2026-03-08T05:48:45Z"
        },
        {
          "tag": "v1.4.2",
          "kind": "patch",
          "published_at": "2026-03-07T20:56:28Z"
        },
        {
          "tag": "v1.4.1",
          "kind": "patch",
          "published_at": "2026-03-06T03:07:11Z"
        },
        {
          "tag": "v1.4.0",
          "kind": "minor",
          "published_at": "2026-03-05T06:16:31Z"
        },
        {
          "tag": "v1.3.1",
          "kind": "patch",
          "published_at": "2026-03-05T03:38:08Z"
        },
        {
          "tag": "v1.3.0",
          "kind": "minor",
          "published_at": "2026-03-05T03:29:47Z"
        },
        {
          "tag": "v1.2.0",
          "kind": "minor",
          "published_at": "2026-03-05T02:26:32Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2026-03-02T03:49:11Z"
        },
        {
          "tag": "v1.0.22",
          "kind": "patch",
          "published_at": "2026-03-01T06:10:46Z"
        },
        {
          "tag": "v1.0.20",
          "kind": "patch",
          "published_at": "2026-03-01T05:50:43Z"
        },
        {
          "tag": "v1.0.19",
          "kind": "patch",
          "published_at": "2026-03-01T04:37:33Z"
        },
        {
          "tag": "v1.0.18",
          "kind": "patch",
          "published_at": "2026-03-01T04:05:15Z"
        },
        {
          "tag": "v1.0.17",
          "kind": "patch",
          "published_at": "2026-03-01T02:50:42Z"
        },
        {
          "tag": "v1.0.16",
          "kind": "patch",
          "published_at": "2026-03-01T02:38:27Z"
        },
        {
          "tag": "v1.0.15",
          "kind": "patch",
          "published_at": "2026-03-01T02:26:50Z"
        },
        {
          "tag": "v1.0.14",
          "kind": "patch",
          "published_at": "2026-03-01T02:11:29Z"
        },
        {
          "tag": "v1.0.13",
          "kind": "patch",
          "published_at": "2026-03-01T01:39:26Z"
        },
        {
          "tag": "v1.0.12",
          "kind": "patch",
          "published_at": "2026-02-28T02:59:21Z"
        },
        {
          "tag": "v1.0.11",
          "kind": "patch",
          "published_at": "2026-02-28T02:55:49Z"
        },
        {
          "tag": "v1.0.9",
          "kind": "patch",
          "published_at": "2026-02-28T00:32:06Z"
        },
        {
          "tag": "v1.0.8",
          "kind": "patch",
          "published_at": "2026-02-27T23:43:40Z"
        },
        {
          "tag": "v1.0.7",
          "kind": "patch",
          "published_at": "2026-02-27T20:53:16Z"
        },
        {
          "tag": "v1.0.6",
          "kind": "patch",
          "published_at": "2026-02-22T06:51:08Z"
        },
        {
          "tag": "v1.0.5",
          "kind": "patch",
          "published_at": "2026-02-22T06:35:36Z"
        },
        {
          "tag": "v1.0.4",
          "kind": "patch",
          "published_at": "2026-02-22T04:34:03Z"
        },
        {
          "tag": "v1.0.3",
          "kind": "patch",
          "published_at": "2026-02-19T02:04:30Z"
        },
        {
          "tag": "v1.0.2",
          "kind": "patch",
          "published_at": "2026-02-18T02:45:43Z"
        },
        {
          "tag": "v1.0.0",
          "kind": "major",
          "published_at": "2026-02-16T23:25:41Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "d188773e88e9e78763a4258fb247599255bfdc9c",
          "body": null,
          "is_bot": false,
          "headline": "v2.2.3 — --json now honours the failure contract on every command",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T22:59:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ddae44a52950517195d4e65a1672719165c29e0",
          "body": "Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01RiL6kNRS8fYCiQ63KXMDYh",
          "is_bot": false,
          "headline": "docs: refresh tests badge to 1815",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T22:59:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c7d942051adfffb330944db31ad782d364851594",
          "body": "…on contract\n\nFollow-up from the PR #80 QC round: README and SKILL.md picked up the `hint`\nfield and serve's channel exception, CLAUDE.md did not. Keeps the in-repo\nguidance for adding new error exits accurate.\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01RiL6kNRS8fYCiQ63KXMDYh",
          "is_bot": false,
          "headline": "docs(CLAUDE.md): note `hint` and serve's stderr exception in the --js…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T18:08:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "383ed0d8b206c166a08fe5ed7925ba88b4082bbc",
          "body": "fix(cli): honour the --json contract on every error-exit path",
          "is_bot": false,
          "headline": "Merge pull request #80 from n1byn1kt/fix/json-error-contract-79",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T18:07:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7e1609aadef8cc7e2ce4ec7887d7a9e2a14ba471",
          "body": "…rror`\n\nActing on the PR #80 QC pass (verdict: approve). Four findings.\n\n1. Medium — the adjacent refresh exit-code fix shipped untested, which is the\n   exact shape of quiet regression that let the original `auth request` bug\n   through. A skill with no oauthConfig, no refreshable tokens and no\n   \n[…]\nand `forget` not-found exit 0) are left as-is, out of scope.\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01RiL6kNRS8fYCiQ63KXMDYh",
          "is_bot": false,
          "headline": "QC round 1: pin the refresh exit-code fix, split help prose out of `e…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T17:45:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2049e3c67b56a2aaf3c53caf2ea2ebefc88c832e",
          "body": "Closes #79.\n\n`--json` on every command is a stated design decision (\"CLI is the API\"),\nbut only the success half was honoured. Usage and validation errors printed\nhuman text to stderr and left stdout empty, so an agent parsing stdout — the\ndocumented machine-output channel — saw nothing at all and h\n[…]\nessed quietly. One test pins\nunchanged human-mode behaviour.\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01RiL6kNRS8fYCiQ63KXMDYh",
          "is_bot": false,
          "headline": "fix(cli): honour the --json contract on every error-exit path",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T17:08:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f15d4c24ea2f7abc15c75c3cac5e5ceb56482c55",
          "body": "fix(cli): add `auth request` subcommand instead of silently parsing it as a domain",
          "is_bot": false,
          "headline": "Merge pull request #78 from n1byn1kt/fix/auth-request-cli-subcommand",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T16:51:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25895145372e5bf91c9b823a744ad03c791fbd06",
          "body": "Review found the primary regression test proved nothing. It ran the handoff\nwith the default 300s timeout, so runCli's 10s execFile kill left stdout\nempty — `parsed?.domain` was undefined and `assert.notEqual(undefined,\n'request')` passed vacuously, at a cost of ~10s per CI run.\n\nNow driven with `--\n[…]\nnnot leak to stdout.\n\nFull suite 1791/1791, typecheck clean.\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01RiL6kNRS8fYCiQ63KXMDYh",
          "is_bot": false,
          "headline": "QC round 1: harden the regression test and fix stale agent docs",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T16:42:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5eb4f95a16e849873eacfa0b227e0cd1acd37cad",
          "body": "…t as a domain\n\n`apitap auth request github.com` parsed \"request\" as the domain name, printed\nan empty-but-valid auth record and exited 0 — while `browse` guidance tells\nagents to run exactly that command. The MCP tool `apitap_auth_request` was\nimplemented all along; only the CLI twin was missing.\n\n\n[…]\nlogin-url/--timeout/--json, matching the MCP tool's surface.\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01RiL6kNRS8fYCiQ63KXMDYh",
          "is_bot": false,
          "headline": "fix(cli): add `auth request` subcommand instead of silently parsing i…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T16:30:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "31cdbaa48ff7b6ccf87f44e94a982a3d8755a4e6",
          "body": null,
          "is_bot": false,
          "headline": "v2.2.2 — auth handoff no longer wipes the captured session",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T16:02:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b697bf274c8268a17fcba2416cb4599b56f5fd87",
          "body": "fix(auth): the login handoff no longer wipes the session it just captured",
          "is_bot": false,
          "headline": "Merge pull request #77 from n1byn1kt/fix/auth-store-drops-session",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T16:02:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "77fbaa836fccda33ac37aa71c14ba8227ff38e51",
          "body": "…ured\n\nFound by writing the first end-to-end test for the apitap_auth_request\npath — browser launch → network sniff → encrypted storage → replay\ninjection. Nothing covered that chain before; test/auth/handoff.test.ts\nonly exercises the detection helpers on synthetic headers.\n\ndoHandoff called storeS\n[…]\nl ordering.\n1785/1785, typecheck clean, new test stable over three runs.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012L2C9ys5cri7JeTyCi4Fv2",
          "is_bot": false,
          "headline": "fix(auth): the login handoff no longer wipes the session it just capt…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-25T01:29:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a625eb3dfd675955e2fcf42600f582e45c47007a",
          "body": "…pinned to code\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012L2C9ys5cri7JeTyCi4Fv2",
          "is_bot": false,
          "headline": "v2.2.1 — browse survives unreadable skill files; Hermes skill claims …",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T23:51:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "83406034d47a8cd9cbd55cc9285e0e141ab6a8ea",
          "body": "Hermes skill: correct 20+ claims the code does not support, and guard them against drift",
          "is_bot": false,
          "headline": "Merge pull request #76 from n1byn1kt/fix/hermes-skill-qc",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T23:50:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9812568e2c5cc5143936696799af4d5e99ccdf71",
          "body": "… the no-endpoint miss exits no_replayable_endpoints\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012L2C9ys5cri7JeTyCi4Fv2",
          "is_bot": false,
          "headline": "hermes skill: round-3 precision — quarantine copy is best-effort, and…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T23:48:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b9b90708bd28f94d69bd8d9a152e17e69986c086",
          "body": "…attach needs no Playwright, four tighter guards\n\ngrok round 2 (12 confirmed, deduped to 7):\n\n- peek's GET fallback downloads the ENTIRE body before discarding it\n  (readBodyLimited does response.text() then slice) — the previous\n  wording claimed a 512KB download cap that only applies to the retain\n[…]\ndiscover guard as satisfiable\nby the handler's third (SSRF error) print.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012L2C9ys5cri7JeTyCi4Fv2",
          "is_bot": false,
          "headline": "hermes skill: round-2 QC fixes — bandwidth truth, browse sequencing, …",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T23:37:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2b9c400034e4958ddc60f82419f63bb66f25fc97",
          "body": "… and five stronger guards\n\ngrok QC round on the PR (3 panels, 17 confirmed findings after skeptic\nverification, deduped to 7):\n\n- The unreadable-skill-file passage now covers both worlds: 2.2.0 aborts\n  browse, newer builds skip the file, report skillFileError (reason\n  unreadable_skill_file), and \n[…]\na simulated\ndrift before being kept — six drifts, one failing test each.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012L2C9ys5cri7JeTyCi4Fv2",
          "is_bot": false,
          "headline": "hermes skill: post-#75 browse contract, sharper cost/browser wording,…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T23:20:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ce4674d19495e35084b4ad0209eb3954324d23ba",
          "body": null,
          "is_bot": false,
          "headline": "merge main (#75 landed: browse skips unreadable skill files)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T23:04:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fea374e089b243ac5cc7ebd85ad0a22b61b00525",
          "body": "fix(browse): an unreadable skill file no longer disables escalation for a domain",
          "is_bot": false,
          "headline": "Merge pull request #75 from n1byn1kt/fix/browse-unreadable-skill-file",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:57:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cfd3e0b970c78f4588f2d397189b7e81cd28c3c9",
          "body": "…te path\n\nSecond grok QC round flagged two real gaps in the quarantine change:\n\n- rename-then-write broke the atomicity the old overwrite had: a writeSF\n  failure after the rename left the domain with no live file at all.\n  preserveSkillFile copies into .quarantine instead, so the live file is\n  onl\n[…]\n so\n  the copy only happens when the disk read actually failed this run.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012L2C9ys5cri7JeTyCi4Fv2",
          "is_bot": false,
          "headline": "fix(browse): preserve by copy, not move, and cover the bridge overwri…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:48:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5710a257163be2a0b889cf287309d331e65e5d78",
          "body": "…es it, and carry skillFileError on every guidance exit\n\nFollow-ups from a grok QC pass on the first version of this fix:\n\n- Discovery success used to silently clobber the unreadable file. That\n  overwrite was unreachable before browse learned to skip bad files, and\n  a cryptographically valid but s\n[…]\nnAPI spec, and a bridge user_denied exit that must keep the\nexplanation.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012L2C9ys5cri7JeTyCi4Fv2",
          "is_bot": false,
          "headline": "fix(browse): quarantine the unreadable file before discovery overwrit…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:37:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3d18e50c46e9e9f4d9681e6bd2bbd69e0459db19",
          "body": "…-json\n\nSame live-agent finding, doc side. Worded to stay true across the fix: 2.2.0\naborts browse on an unreadable file, newer builds skip it and keep escalating,\nand the recovery (re-capture or re-import) is the same either way.",
          "is_bot": false,
          "headline": "hermes skill: note that an unreadable skill file can silence browse -…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:10:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "46c96991a954e932c140bd398b2682b902e76ad5",
          "body": "…OS too\n\nRound 6 (fable). The previous commit fixed a real defect by over-correcting\ninto the opposite false absolute: it told macOS agents to give up on login\nwalls unconditionally.\n\nThe DISPLAY switch governs only the browser capture LAUNCHES. Before launching,\nconnectToBrowser tries to join a Chr\n[…]\ntractor treated Chrome's --remote-debugging-port as an apitap flag and\ndemanded src/cli.ts read it. It now skips code chunks belonging to other tools,\nand still fails on a fake apitap flag (verified).",
          "is_bot": false,
          "headline": "hermes skill: the CDP-attach route makes a manual sign-in work on mac…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:10:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b62279127af10d51181591882da371953bc40476",
          "body": "…in route is Linux-desktop only\n\nRound 5. Fable found nothing; grok found two, one of them real and pointed at\na recommendation Fable had explicitly re-verified as sound.\n\n- \"On a desktop host, apitap capture after a manual sign-in is worth trying\"\n  is wrong on macOS, which this skill's platforms l\n[…]\ning.\n\nNew guard ties the sign-in advice to the DISPLAY expression and to the absence\nof a headed/headless CLI flag, and requires the document to keep explaining\nDISPLAY. Proven red in both directions.",
          "is_bot": false,
          "headline": "hermes skill: capture is headless unless DISPLAY is set, so the sign-…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:10:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b698e04ce42ce4b7fe1465c4a310fd282ad65fb9",
          "body": "…ess on login walls two ways\n\nRound 4 (grok, 9 confirmed findings). Two of these were in sentences written\nduring rounds 3 and 4 — including one added minutes earlier — which is the\nfourth and fifth time a fix for this defect class introduced a new false claim.\n\n- \"The fix is apitap capture\" over-pr\n[…]\nired in the prose\n(previously only --fresh and 401/403 were), and a new guard ties the browse\nlogin-wall warning to the read-fallback success condition in browse.ts. All\nthree proven to fail on drift.",
          "is_bot": false,
          "headline": "hermes skill: capture is not a general login fix; browse reports succ…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:10:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "67dbd584220f8ed4ef45f7dfa4aa81ed82ed34df",
          "body": "Fable's round-4 pass returned no ship-blockers and verified the consolidated\nreplay/browser rule clause by clause. Two residual inaccuracies, both taken:\n\n- apitap inspect also prints a bare usage line rather than an \"Error:\" prefix\n  on a missing argument (cli.ts:2021), so it joins apitap index in \n[…]\ns its shape — it fails if the parser learns to split on \"=\" while the\ndocument still warns, and fails if the document drops the warning while the\nparser still ignores the form. Both directions proven.",
          "is_bot": false,
          "headline": "hermes skill: round-4 accuracy minors and an equals-form guard",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:10:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4de9e150e4b1019410bcd3447254a715c0dfaee4",
          "body": "…h rule once\n\nRound 3 (grok, 12 confirmed findings). The replay/browser correction had been\nparaphrased in four places and three of the paraphrases were wrong, so the rule\nnow lives in Setup only and everything else defers to it.\n\n- \"Login walls have no CLI fix\" was false. apitap capture on a host w\n[…]\n) and the two named triggers. New guard reads the\ndocument's own \"These never launch one\" list and fails if a browser-driving\ncommand appears in it — the module scan could not see that class of error.",
          "is_bot": false,
          "headline": "hermes skill: the CLI does have a login path; state the replay refres…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:10:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "42e0d13e3d4880fa22288bf8ff0f8c4df50ba2e8",
          "body": "…y-browser claim to the skill file\n\nRound 3 (fable). Two of the sentences the previous commit rewrote carried\nfresh absolutes with counterexamples in src/ — the third time a fix for this\nclass introduced one of its own.\n\n- \"Replay of a public endpoint never does\" was wrong: needsBrowser collects\n  r\n[…]\n pins the document's load-bearing condition to\nthe needsBrowser expression by equality; a substring match let an added term\npass, which is how the first version of this guard failed its own RED proof.",
          "is_bot": false,
          "headline": "hermes skill: equals-form flags are silently dropped; scope the repla…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:10:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "10846fb6c834d5c7b0fe94c868fb194b4275d372",
          "body": "…(grok re-review)\n\ngrok's re-review found what the first pass and both earlier reviewers missed:\n'no browser anywhere in the replay path' is false, and it was the document's\nheadline sentence plus its cost table, Setup list and Procedure step.\n\nhandleReplay always passes authManager (cli.ts:541); re\n[…]\nan explanation that was wrong even though its conclusion was right:\n  handleReplay reads flags.json before the skill-not-found branch, so 'the\n  check runs before the flag is read' did not hold there.",
          "is_bot": false,
          "headline": "hermes skill: replay can open a browser — correct the headline claim …",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:10:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "486b7e92c4725541e028d3902d8029e0a08844a7",
          "body": "…guard the real browser entry points\n\nFable's re-review confirmed all 12 corrected claims against source but caught\nthe fix repeating the defect class it was fixing: 'only capture needs a\nbrowser' had been corrected to 'three commands drive a browser', which is\nalso false — handleInspect calls the s\n[…]\nes.\n- Scoped two remaining absolutes: audit also emits the stale-index notice,\n  and the stderr-on-bad-argument rule holds for the commands in this file\n  (swaggerhub/github import and doctor differ).",
          "is_bot": false,
          "headline": "hermes skill: fix re-review findings — inspect drives a browser too, …",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:10:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "495a9ac8d95b92c7c5f811dc65445ad96c4e2c15",
          "body": "Both reviewers independently found the skill document asserts runtime\nbehaviour ApiTap does not have. Every fix below is verified against source\nand, where observable, against a live run.\n\n- capture blocks on SIGINT forever without --duration (monitor.ts:225-234);\n  under --json it prints nothing wh\n[…]\n, capture's blocking behaviour must still justify\nthe --duration warning, auth_required must stay confined to peek, and index\nbuild must stay outside the --json contract. Each proven to fail on drift.",
          "is_bot": false,
          "headline": "hermes skill: fix 13 claims the code does not support (grok + fable QC)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:10:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "83098fc3b59f9b8becf7c705aa0657f6b00e5f71",
          "body": "…out loud\n\nFable's consult on the previous commit found a gap in its own goal and one\nmissing behaviour.\n\n- skillFileError rode only the final `if (!skill)` exit. When discovery runs\n  and finds nothing usable, browse leaves through no_replayable_endpoints —\n  which is the likely exit for the api.gi\n[…]\nion is what apitap doctor's quarantine is for.\n\nTest also tightened: it now asserts skillFileError itself rather than matching\na regex that the reason string 'unreadable_skill_file' already satisfied.",
          "is_bot": false,
          "headline": "fix(browse): carry the skipped-file reason on every exit, and say it …",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:09:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b0e353f69e68044fca1ac8984e4ce9fea022af92",
          "body": "…lation\n\nFound by driving the Hermes skill against a live agent (grok-4.5) rather than\nby review: asked to fetch a login-walled GitHub endpoint, the agent dead-ended\nbecause a stale-signature skill file for api.github.com killed browse outright.\n\nbrowse.ts:198 called readSkillFile unguarded, so the \n[…]\n with no saved file at all.\n\nTest reproduces the exact failure — a signed skill file with its signature\ncorrupted, which threw before this change and now returns guidance naming the\nsignature problem.",
          "is_bot": false,
          "headline": "fix(browse): an unreadable skill file no longer aborts the whole esca…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T22:09:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5c7d71145e2887da20f4cedcac16b0226702d151",
          "body": "* hermes skill: frontmatter + contract test\n\n* hermes skill: body, CLI-truth test\n\n* README: Use with Hermes install section\n\n* hermes skill: fix final-review findings — machine-bound signatures, --json scope, drift guard gaps\n\nSKILL.md: drop the \"copyable to another machine\" portability claim (skil\n[…]\ngnature expiry, drop 'forever' claim\n\n* hermes skill: document invalid/stale signature recovery (found dogfooding on jfk)\n\n---------\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Hermes skill: install ApiTap into Hermes Agent in one command (#74)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-24T19:22:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cd1c1b79ba2a1f1a942b41fcca7c2e4181b163e4",
          "body": "Post-ship hygiene from the 2026-07-20 QC pass: the changelog stopped at\nv2.1.1 while the tag/release/npm were already at 2.2.0; mirror the\nrelease body into CHANGELOG.md and give the envelope-cap floor case a\nconcrete number in the README.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01E6MWEdYdM9jpdnXLzQhZcz",
          "is_bot": false,
          "headline": "docs: v2.2.0 changelog section + maxBytes floor-case example in README",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T20:11:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "cec2df33874dd9a368c83eed7306d250615ae156",
          "body": "…s envelope, read-path fixes\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01JQaJk5nQXmddqC2P4ZQrVz",
          "is_bot": false,
          "headline": "v2.2.0 — agent-UX batch: doctor summary, search ranking, hard maxByte…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T04:03:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ba74a8265bad0e649abe26d2fd61cbe09fd7166f",
          "body": "read-path batch: Wikipedia full article, lobste.rs decoder, --json stderr hygiene",
          "is_bot": false,
          "headline": "Merge pull request #73 from n1byn1kt/fix/read-path-batch",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T04:02:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7fe3931247a6219206f67d77801bac615601fad9",
          "body": null,
          "is_bot": false,
          "headline": "merge main (PR3 landed)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T04:02:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "01b88a6af2e385cdfed6533e4f53b018e86756f5",
          "body": "maxBytes is now a hard envelope cap + envelopeBytes everywhere",
          "is_bot": false,
          "headline": "Merge pull request #71 from n1byn1kt/fix/maxbytes-envelope-cap",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T04:01:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a2f1159363813ba814156301d38a0b71bf1b18f0",
          "body": "search: locality+tier+provenance ranking demotes apis.guru import noise",
          "is_bot": false,
          "headline": "Merge pull request #70 from n1byn1kt/fix/search-ranking",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T04:01:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "56b33fd8ec75554aa1c4a3945c6ca00885982d2d",
          "body": "doctor UX: summary-first default + --help fix",
          "is_bot": false,
          "headline": "Merge pull request #69 from n1byn1kt/fix/doctor-summary",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T04:01:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "17eed5680eed119a953de33f05935cdb1217ac7d",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'fix/maxbytes-envelope-cap' into fix/read-path-batch",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T04:00:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "62184a4b2bce9f6ba80adeef9d6d3057cba13a45",
          "body": "…polish\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01JQaJk5nQXmddqC2P4ZQrVz",
          "is_bot": false,
          "headline": "fix: read --json compact emission matches cap measurement + envelope …",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T04:00:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0f31180fbc4efa05c6579d580b43063d60cef345",
          "body": "…clean\n\nRoute handleReplay and handleBrowse warning-class stderr writes (auth-missing\nhint, SSRF-disabled banner, endpoint-upgrade note, confidence hint) into a\n`notices: string[]` field on the JSON envelope, inside the capEnvelope build\ncallback so notices count toward and survive the byte cap. Non\n[…]\n unaffected — its only stderr writes are\nhard errors with non-zero exit.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01JQaJk5nQXmddqC2P4ZQrVz",
          "is_bot": false,
          "headline": "fix(cli): --json runs emit warnings as envelope notices, keep stderr …",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T03:48:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d328ca2e73ffe3ab969f707c952021dea05bfca8",
          "body": "Fixes from review:\n- decode() awaits decodeStory/decodeFront so later rejections are caught,\n  preserving the return-null-on-any-failure contract\n- explicit /newest vs /recent (falls to hottest.json) vs bare front-page\n  feed routing, no silent fall-through\n- guard malformed/null entries in the front-page stories array instead of\n  throwing mid-map\n- description populated on both front-page and story results",
          "is_bot": false,
          "headline": "feat(read): native lobste.rs decoder via JSON endpoints",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T03:40:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "41886784a6a3cb844764a7d1ebae24a79b160db7",
          "body": "… fallback",
          "is_bot": false,
          "headline": "feat(read): Wikipedia full-article body via action-API extracts, lede…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T03:33:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "40d3c6879f3fdeda31260cc02fda82aebd67b74e",
          "body": "…tes + maxBytes docs\n\nExtracts the v2.0.1 re-slice loop into fitReadEnvelope and applies it to\nsite-decoder results too (previously bypassed the envelope diet via early\nreturn). envelopeBytes recorded on every read envelope; README documents\nhard-cap semantics incl. the floor exception.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01JQaJk5nQXmddqC2P4ZQrVz",
          "is_bot": false,
          "headline": "feat(read): decoder envelope fitting via fitReadEnvelope + envelopeBy…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T03:30:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f2ce3e431cf54fddc6df563d2dfd2f528d469982",
          "body": "…e/replay_batch",
          "is_bot": false,
          "headline": "feat(mcp): hard maxBytes envelope cap + envelopeBytes on replay/brows…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T03:15:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "900e99dd7ab4c14cd570947cd4e3d48eda473967",
          "body": "…e --json\n\nWires Task 5's capEnvelope into handleReplay and handleBrowse's --json\nbranches using the placeholder-envelopeBytes trick, so --json stdout is\nhard-capped at --max-bytes and always carries a numeric envelopeBytes\nsibling of truncated.",
          "is_bot": false,
          "headline": "feat(cli): hard maxBytes envelope cap + envelopeBytes on replay/brows…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T03:06:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7acb787d13b61546c592a5668fe105865d804414",
          "body": "…lopes\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01JQaJk5nQXmddqC2P4ZQrVz",
          "is_bot": false,
          "headline": "feat(replay): capEnvelope — hard byte cap on serialized response enve…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T02:57:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b3375b07049f4de175693d7796eb574cfc560e83",
          "body": "…t noise\n\nsearchSkills now sorts every result (not just when truncating) by\nmatch locality (domain > endpoint id > path), then replayability\ntier, then provenance (self > imported-signed > imported > unsigned),\nbefore falling back to original order. Uses the index's existing\nper-domain provenance field — no index rebuild needed. SearchResult\ngains `provenance`; new exported PROVENANCE_RANK. Updates the\napitap_search MCP tool description to match.",
          "is_bot": false,
          "headline": "feat(search): rank by match locality, tier, provenance — demote impor…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T02:41:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e289097ce4afec87f9bb27864112724ff3412231",
          "body": "Whole-store `apitap doctor` now prints formatDoctorSummary (per-check\ncounts + severity-weighted top domains) instead of 300+ raw finding\nlines. --verbose or a positional domain still gets the full\nformatDoctorReport dump. --json and exit codes are unchanged.",
          "is_bot": false,
          "headline": "feat(doctor): summary-first default output, --verbose for full dump",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T02:34:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "068d169366972fbe3a12a2bcb8c54d7dfca37661",
          "body": "…ted top domains",
          "is_bot": false,
          "headline": "feat(doctor): summary-first formatter with per-check counts and weigh…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T02:29:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0e4cadf07ddd164834d9fd7e4ad9d0fab60bae45",
          "body": null,
          "is_bot": false,
          "headline": "fix(doctor): --help/-h prints usage instead of running a scan",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-20T02:26:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "037b3fd1a03dd9d2262ced1194bdc615a63f5a2f",
          "body": "…port errors, challenge interstitials\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01G7nDVVCHyQfffUNB31LSkS",
          "is_bot": false,
          "headline": "v2.1.1 — agent-trust honesty batch: example-param seeding, peek trans…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T21:48:58Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c68c537209c5f9141a97eb3fcd6b0d25eac850ea",
          "body": "Reddit's \"please wait for verification\" page (and Cloudflare's \"Just a\nmoment…\") answer HTTP 200 with a verification interstitial. The generic\nread pipeline extracted it as a green success with empty content — the\nlast silent-trust failure from the 2026-07-19 wild gauntlet.\n\nNew src/read/challenge.t\n[…]\nd — when extraction is empty — an\nexplicit content note instead of \"\".\n\n\nClaude-Session: https://claude.ai/code/session_01G7nDVVCHyQfffUNB31LSkS\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "read: label bot-challenge interstitials instead of empty success (#68)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T21:38:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "827ed4950bc3e56f71c8e54a4b2ca16507b125cc",
          "body": "…st peek transport errors (#67)\n\nTwo fixes from the 2026-07-19 wild dogfood gauntlet:\n\n1. Replay silent empty success (open-meteo class): when a skill's\n   queryParams is empty but the captured example URL carries a query\n   string, seed the request from the example. Previously the call went\n   out \n[…]\ntion\" note, and SSRF-blocked URLs say so instead of\n   \"fetch failed\".\n\n\nClaude-Session: https://claude.ai/code/session_01G7nDVVCHyQfffUNB31LSkS\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Agent-trust honesty: seed replay query params from example URL + hone…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T21:32:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "005d10cc4d4c7382ffacdbf0ecfd45018968f06c",
          "body": "Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_019MNoD29QgKynL4uDXrCRdj",
          "is_bot": false,
          "headline": "v2.1.0 — apitap doctor: offline skill-store hygiene lint",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T21:07:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5083273ca26bdc2849f109479fa93548bd18ce5e",
          "body": "…fix (#66)\n\n* feat(doctor): types, soft loader, invalid-signature findings\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n* feat(doctor): snapshot/quarantine/restore with refusal + .orig precedence\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n* feat(doctor): beacon-endpoints ch\n[…]\ning — domain validation, non-clobbering quarantine, domain-mismatch edit gate\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "apitap doctor — offline skill-store hygiene lint with conservative --…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T21:05:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1dcdd9b400ca646c1592f191b013853693abca63",
          "body": "…ice, SSRF guard\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01X28bnPQoDouurPBZip84NQ",
          "is_bot": false,
          "headline": "v2.0.1 — issue batch: truncation performance + bounds, envelope re-sl…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T19:39:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "37da60d9fee2376871ad61070981b4b5b57b4bc1",
          "body": "…SRF-consistency (#63, #64) (#65)\n\n* truncate: O(n) array truncation — per-item sizes instead of pop-loop re-serialization\n\nThe pop loop re-stringified the whole array per dropped item, so a 50k-item\nresponse took minutes (measured >120s; 20k items ~26s). Serialize each item\nonce, compute the exact \n[…]\ns #64\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01X28bnPQoDouurPBZip84NQ\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Issue batch: truncation bounds (#60, #61), envelope re-slice (#62), S…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T19:39:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "04c9d0556ba7994c5615141a04d43d9db92c6d37",
          "body": null,
          "is_bot": false,
          "headline": "v2.0.0 — maxBytes honesty: recursive truncation + envelope diet",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T18:46:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "05209cc97fe7d26d7a8314c74006232c650c4847",
          "body": "… + read envelope diet (#59)\n\n* fix(replay): recursive budget-aware truncation with structured metadata\n\n* fix(replay): propagate structured truncation metadata through engine, batch, browse\n\nEngine and batch replay call sites, browse.ts, and the MCP apitap_replay\nhandler were all re-stamping boolea\n[…]\nrding\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01LGCuodgupuMcrGs4dWA67e\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: maxBytes honesty — recursive truncation with structured metadata…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T18:41:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8d72584acbc4bc0b80fafc59cdc1f49c93f273d0",
          "body": "GitHub's licensee scans root LICENSE* files; the declaration doc matched\nthe glob and showed as \"Unknown license\" next to Apache-2.0 in the repo\nsidebar. Renamed outside the pattern; content unchanged.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01LGCuodgupuMcrGs4dWA67e",
          "is_bot": false,
          "headline": "chore: rename LICENSE-CHANGE.md → RELICENSING.md",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T17:37:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "153cb970eb406baac4ed25b287acaa0d20688c37",
          "body": "Drops the 6,400+ pre-mapped endpoints headline (June strategy flagged the\ncorpus count as inflated; keyless replay of imported commercial APIs\nmeasured ~zero usable). Keeps the \"any website into an API\" one-liner.\nIntro now leads with capture → signed skill file → verified replay and\nthe auth-separa\n[…]\nient?\" FAQ entry aimed at the raw-HAR workflow.\nTests badge 1590 → 1601.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01LGCuodgupuMcrGs4dWA67e",
          "is_bot": false,
          "headline": "docs: hybrid positioning — capture→replay→verify leads, import demoted",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T16:35:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e98d2ca81c2e5a1ccb23141c937fcae618bfbf8a",
          "body": null,
          "is_bot": false,
          "headline": "1.13.0",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T16:26:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8a1ce289bdee390f2e76bcb9513d402cd346d497",
          "body": "Invokes the BSL 1.1 early-conversion clause (\"or if earlier, upon the\noccurrence of an event specified by Licensor\") three years ahead of the\nFebruary 2029 Change Date. Declaration in LICENSE-CHANGE.md. All prior\nreleased versions convert with it.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01LGCuodgupuMcrGs4dWA67e",
          "is_bot": false,
          "headline": "ApiTap is now Apache 2.0",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T16:26:44Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0d46f469ab1eed1a379723fc5ffea7a66ee7fded",
          "body": "cf-ray alone marked half the CDN-fronted web \"blocked\" even on a 200,\nwhile real bot fortresses that only challenge deeper paths showed\nbotProtection: null off a landing-page HEAD. Now: CDN presence is just\na signal; only bot-management evidence (challenge cookies, mitigation\nheaders) names a vendor\n[…]\nadds a \"deeper paths may challenge\" signal\ninstead of a false \"blocked\".\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01LGCuodgupuMcrGs4dWA67e",
          "is_bot": false,
          "headline": "fix(peek): honest bot-protection triage in both directions",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T16:23:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "aa2e47a6431f92f0eda72ad466656ca4e55bcee6",
          "body": "The Firebase API returns comment bodies as encoded rich text (<p>,\n&#x27;, encoded hrefs) and the decoder passed them through verbatim.\nNew htmlSnippetToText helper in extract.ts: numeric entity decoding\n(hex + decimal), <p> to paragraph breaks, <a> to markdown links (or\nbare URL when HN truncated the label), <pre><code> to fenced blocks.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01LGCuodgupuMcrGs4dWA67e",
          "is_bot": false,
          "headline": "fix(read): HN decoder returns readable text, not escaped HTML",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T16:23:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a9715f49805c46bef3a268b25182458fe3b8a7e9",
          "body": "A broad query over the preloaded spec catalog returned every matching\nendpoint — 1.4 MB in one response, enough to blow any agent context.\nTruncation keeps the most replayable results (green > yellow > unknown >\norange > red, stable within tier), sets truncated: true with a\nnarrow-the-query summary,\n[…]\nno-match suggestion now lists at most 20 domains instead of all of them.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01LGCuodgupuMcrGs4dWA67e",
          "is_bot": false,
          "headline": "fix(search): cap results at 50 with tier-ranked truncation",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T16:23:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7ea3babb8b6ba1f2874ca312e96f5d3a47ad3518",
          "body": null,
          "is_bot": false,
          "headline": "1.12.2",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T15:51:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d80e7ab85dff74609080c2e889de4aa8e4b6483b",
          "body": "Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01LGCuodgupuMcrGs4dWA67e",
          "is_bot": false,
          "headline": "docs: tests badge 1587 → 1590",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T15:51:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1a5a4d906c9592eb72b0679806f4d8a88ecb4906",
          "body": "…ng endpoint (#52)\n\npickEndpoint matched paths by bidirectional substring and fell back to\ncandidates[0] unconditionally, so browsing /users/octocat on a domain\nwhere only GET /users was captured silently replayed the list endpoint\n— success: true with data for a different resource.\n\nMatch segment-b\n[…]\nin browse keeps its pick-a-representative-endpoint behavior.\n\nCloses #52\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01LGCuodgupuMcrGs4dWA67e",
          "is_bot": false,
          "headline": "fix(browse): require route-template match — no silent fallback to wro…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-07-19T15:47:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "86ff710c54decf24ce739cd0bd704be99cd17721",
          "body": null,
          "is_bot": false,
          "headline": "feat(dane-catalog): scaffold types and test fixtures",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-05-29T03:38:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7f1744420a1f347092657d4309a49c6419a82613",
          "body": "* test: skip CDP-attach integration when debug port never binds (de-flake CI)\n\nThe test gates on `which google-chrome`, but Chrome being installed doesn't\nguarantee its remote-debugging port comes up — in constrained CI sandboxes\nit sometimes never binds, and the test failed with ECONNREFUSED. Track\n[…]\n+https://...\" warning npm\nemits on every publish.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: de-flake CDP-attach CI test + normalize repository.url (#58)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-05-29T03:00:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f19d3490e410c6243882467de3dc71543534976f",
          "body": null,
          "is_bot": false,
          "headline": "1.12.1",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-05-29T02:21:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bfc6e376819992f944ca7be3b830bdd80bac5dbf",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: test badge 1587 + v1.12.1 changelog",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-05-29T02:21:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "af43fbb101d9fde93cb154b77755de6e22df7d42",
          "body": "…ing (#55) (#56)\n\nCaptureSession.finish() built the skill from only the current session's\nexchanges and wrote it with writeSkillFile(), wholesale-replacing any\nexisting on-disk skill for that domain. Re-capturing a domain (e.g.\ndrilling into one resource) silently dropped every endpoint captured in\n\n[…]\nll/preserve/update/\ndistinct-method/base) + a live-session integration test asserting a\npre-seeded endpoint survives a re-capture.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(capture): merge with existing skill on finish instead of overwrit…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-05-29T02:20:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "04b846fe1c6f176dd461e5611da18a80c6d0047a",
          "body": null,
          "is_bot": false,
          "headline": "1.12.0",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-05-29T01:36:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a81fb27684c89cdd07d69de71e4032fa0153857c",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: update test badge to 1581 and add v1.12.0 changelog",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-05-29T01:34:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e4b6f2d850fd415afa12d882e3f9db47c133fedd",
          "body": "* fix(security): authenticate provenance and stop imported files bypassing verification\n\nH1: canonicalize() now includes `provenance` in the signed payload so the\ntrust label is tamper-evident, and signSkillFile/signSkillFileAs set\nprovenance before signing. readSkillFile no longer has an `imported`\n[…]\nunrelated access_token value is not mis-captured.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Security & privacy audit fixes (#54)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-05-29T01:31:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "85c009cc5190b89a88f7ec906052eba93de7b7bb",
          "body": "Minor version bump for trap-aware v1.0 feature: trap-aware content\nscanning on apitap read (always-on, annotate-only) and opt-in\noutbound egress checks on apitap replay. Backward-compatible for all\nexisting users — default behavior is byte-identical.\n\nTest count: 1427 → 1517 (+90 new trap-aware tests added in f03bbcb).\n\nNo npm publish yet — this is the version bump commit only.",
          "is_bot": false,
          "headline": "chore: bump version to v1.11.0 and update test count badge",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-04-08T22:11:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f166140d0c44291a5e03adc6a9c65d807b101255",
          "body": "GitHub's secret scanner detected the literal \"tskey-auth-...\" fixture\nin test/replay/egress-patterns.test.ts as a real Tailscale API key\n(alert #2). It is synthetic — only used to verify the egress scanner's\nsecret_tailscale_auth_key regex matches — but Tailscale auth keys are\npattern-matched by Git\n[…]\nhropic,\nSlack, npm) were not flagged because GitHub validates those via callback\nand synthetic ones fail validation. If any of those start getting flagged\nin the future, apply the same join() pattern.",
          "is_bot": false,
          "headline": "fix(test): split synthetic Tailscale token to avoid secret-scan flag",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-04-07T05:31:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c2913bb0c5bea1ac0a3dc67e4f9339a2bc9f82e2",
          "body": "The existing rule covered docs/plans/ but not the parallel\ndocs/superpowers/plans/ and docs/superpowers/specs/ paths used by\nthe brainstorming/planning workflow. Add both to prevent internal\ndesign docs from accidentally landing in commits.",
          "is_bot": false,
          "headline": "chore: gitignore docs/superpowers/plans/ and specs/",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-04-07T05:16:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f03bbcb224ccec0c6f8a11b13f48118c360f0ce3",
          "body": "… for replay (#50)\n\nAdds trap-aware content scanning to apitap read (always-on, annotate-only) and opt-in outbound egress checks to apitap replay. Byte-identical behavior for existing users who don't opt in — enforced by a dedicated cron-job contract test.\n\n- Read scanner: two-condition gated (hidde\n[…]\nress check, plus a redaction contract test that scans for secret substrings in serialized finding output.\n\nFull per-commit history and design doc references: https://github.com/n1byn1kt/apitap/pull/50",
          "is_bot": false,
          "headline": "feat: trap-aware v1.0 — content scanner for read, opt-in egress check…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-04-07T05:05:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "65b5153630e9ecb53f85d217f27289ab99da6c5f",
          "body": null,
          "is_bot": false,
          "headline": "docs: update description to mention CLI, MCP server, and npm library",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-04-03T19:25:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5664f01b86dabb07d8839c67c4e13215287cbfd0",
          "body": null,
          "is_bot": false,
          "headline": "1.10.2",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-04-03T17:12:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95b81c379d4d89afe58e6ab343d01fde0c6f6e2d",
          "body": null,
          "is_bot": false,
          "headline": "chore: update test count badges to 1427",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-04-03T17:11:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a709a69cc3066f2d46a9b98616d2235b1c8a49ae",
          "body": null,
          "is_bot": false,
          "headline": "fix: add fallback for pre-Feb-22 fixed-salt signature verification (#49)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-04-03T17:10:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "389a814424a2fd1db9711a26c9d33c4de263d4d4",
          "body": null,
          "is_bot": false,
          "headline": "docs: document apitap mcp subcommand, fix #46 (#47)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-04-03T16:55:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0260fa93bf22a371b9add9933a0a859cf01b049",
          "body": "… (#48)",
          "is_bot": false,
          "headline": "fix: add legacy canonicalization fallback for pre-March-5 skill files…",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-04-03T16:54:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "baf8f2c9ed8254d77d608f864adac0133396790c",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump path-to-regexp to 8.4.2, security patch release v1.10.1",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-04-02T13:21:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d8054f8a4448907185f5e13e850a3e7c007f6f99",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to v1.10.0",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-03-29T20:02:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0608575c01cc218a25e08a08cb24fa608cfdf8e5",
          "body": "* feat: add known-specs.json and --from known import source (#43)\n\nAdd curated registry of 54 major API providers with verified OpenAPI spec\nURLs. New `--from known` flag on the import command lets users import all\nknown specs or filter by provider name with `--query`.\n\nCo-Authored-By: Claude Opus 4\n[…]\nropic.com>\n\n---------\n\nCo-authored-by: Clawd <clawd@localhost>\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat: add known-specs.json and --from known import source (#43) (#44)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-03-29T20:01:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1c68717771bc604b626b528ea6acd6b85efb0728",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to v1.9.4",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-03-22T04:09:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b6b42514815d061bd6dcb0930e448abc14e456c3",
          "body": "Add specs/, reference/, openapi/ to probe directories. IRL testing\nshowed Discord specs live in specs/, PagerDuty in reference/, and\nFigma in openapi/. These are common directories for API spec repos\nthat the original api/, spec/, docs/ set missed.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(github): expand probe dirs for spec discovery",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-03-22T04:02:42Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "488d8164b2763ae182f156b08b107f7ebdf23d6e",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to v1.9.3",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-03-22T04:00:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0be946b4191e9503f2589dadeae8967946ea5dff",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to v1.9.2",
          "author_name": "Clawd",
          "author_login": null,
          "committed_at": "2026-03-22T03:43:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "414649707ac3653c48557cda6f135b446f2480c0",
          "body": "Address two follow-up medium findings:\n- scrub sensitive values from schema-aligned examples.request.headers in export sanitization (retain legacy exampleRequestHeaders compatibility)\n- add explicit passive indexing opt-in in extension settings and gate background webRequest observation behind passiveIndexEnabled (default off)\n\nAlso add regression tests for both paths.\n\nCo-authored-by: Clawd <clawd@localhost>\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
          "is_bot": false,
          "headline": "fix(extension): scrub example headers and gate passive indexing (#41)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-03-22T03:43:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bb00cea052f6d9139a47630e1ae4ba9f47dd51fd",
          "body": "GitHub's Code Search API doesn't reliably index spec files (e.g.,\ncloudflare/api-schemas is invisible to it). Add a name-heuristic\nfallback: after code search, list the org's repos (up to 300, sorted\nby stars) and probe repos whose names match API-spec patterns\n(api-spec, api-schema, openapi, swagge\n[…]\n limit errors (403/429)\ngracefully fall through to the heuristic phase instead of failing.\n\nCo-authored-by: Clawd <clawd@localhost>\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(github): hybrid org scan — code search + name-heuristic probe (#42)",
          "author_name": "n1byn1kt",
          "author_login": "n1byn1kt",
          "committed_at": "2026-03-22T03:41:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 64,
      "commits_last_year": 374,
      "latest_release_at": "2026-07-25T22:59:20Z",
      "latest_release_tag": "v2.2.3",
      "releases_from_tags": false,
      "days_since_last_push": 10,
      "active_weeks_last_year": 12,
      "days_since_latest_release": 10,
      "mean_days_between_releases": 0.7
    },
    "artifacts": {
      "collected": true,
      "structure": [],
      "declarations": [
        {
          "name": "extension",
          "path": "extension/package.json",
          "tokens": [
            "npm.entry"
          ],
          "ecosystem": "npm"
        },
        {
          "name": "@apitap/core",
          "path": "package.json",
          "tokens": [
            "npm.bin",
            "npm.entry"
          ],
          "ecosystem": "npm"
        }
      ]
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "readme_badges": {
        "hosts": [
          "shields.io"
        ],
        "total": 3,
        "header": 3,
        "collected": true,
        "has_inspect_badge": false
      },
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 85,
      "has_issue_template": false,
      "has_code_of_conduct": true,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@apitap/core",
          "exists": true,
          "license": "Apache-2.0",
          "keywords": [
            "api",
            "interception",
            "ai-agent",
            "mcp",
            "browser-automation",
            "web-scraping",
            "playwright",
            "skill-file",
            "api-discovery"
          ],
          "ecosystem": "npm",
          "categories": [],
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@apitap/core",
          "declared_type": null,
          "is_deprecated": false,
          "latest_version": "2.2.2",
          "repository_url": "https://github.com/n1byn1kt/apitap",
          "versions_count": 66,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 2030,
          "first_published_at": "2026-02-16T23:13:33.765000Z",
          "latest_published_at": "2026-07-25T16:04:07.868000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 11
        },
        {
          "name": "extension",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "browser extension framework",
            "chrome extension framework",
            "web extension framework",
            "zero-config",
            "build",
            "develop",
            "browser",
            "extension",
            "chrome extension",
            "edge extension",
            "firefox extension",
            "safari extension",
            "web",
            "react",
            "typescript",
            "webextension",
            "browser-extension",
            "chrome-extension",
            "firefox-addon",
            "edge-extension",
            "safari-web-extension",
            "manifest-v3",
            "mv3",
            "cross-browser",
            "content-script",
            "background-script",
            "devtools",
            "create-extension",
            "scaffold",
            "starter-template",
            "boilerplate",
            "cli"
          ],
          "ecosystem": "npm",
          "categories": [],
          "matches_repo": false,
          "registry_url": "https://www.npmjs.com/package/extension",
          "declared_type": null,
          "is_deprecated": false,
          "latest_version": "4.0.30",
          "repository_url": "https://github.com/extension-js/extension.js",
          "versions_count": 523,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 25324,
          "first_published_at": "2012-02-24T20:41:22.249000Z",
          "latest_published_at": "2026-08-04T23:10:33.380000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 9,
      "stars": 123,
      "watchers": 1,
      "fork_history": {
        "days": [
          {
            "date": "2026-02-27",
            "count": 2
          },
          {
            "date": "2026-03-02",
            "count": 1
          },
          {
            "date": "2026-03-03",
            "count": 1
          },
          {
            "date": "2026-03-04",
            "count": 1
          },
          {
            "date": "2026-03-11",
            "count": 1
          },
          {
            "date": "2026-03-15",
            "count": 1
          },
          {
            "date": "2026-04-28",
            "count": 1
          },
          {
            "date": "2026-07-21",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 9,
        "total_forks": 9
      },
      "star_history": null,
      "open_issues_and_prs": 1
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "extension/tsconfig.json",
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 101477,
      "source_files_sampled": 285,
      "oversized_source_files": 1,
      "agent_instruction_files": [
        ".github/copilot-instructions.md",
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 6841
    },
    "dependencies": {
      "manifests": [
        "extension/package.json",
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [
          {
            "name": "hono",
            "direct": false,
            "version": "4.12.33",
            "severity": "moderate",
            "ecosystem": "npm",
            "cvss_score": 5.3,
            "advisory_ids": [
              "GHSA-8j4g-w8fx-2239"
            ],
            "fixed_version": "4.12.34",
            "advisory_count": 1,
            "oldest_advisory_days": 2
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "moderate": 1
        },
        "advisory_count": 1,
        "affected_count": 1,
        "assessed_count": 100,
        "malicious_count": 0,
        "assessed_package": "npm:@apitap/core@2.2.2",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@modelcontextprotocol/sdk",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.26.0"
        },
        {
          "name": "js-yaml",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.1.1"
        },
        {
          "name": "playwright",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.58.1"
        },
        {
          "name": "zod",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.3.6"
        }
      ],
      "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": 52,
        "open_issues": 1,
        "closed_ratio": 0.957,
        "closed_issues": 22,
        "closed_unmerged_prs": 4
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "n1byn1kt",
          "commits": 113,
          "avatar_url": "https://avatars.githubusercontent.com/u/242883047?v=4"
        },
        {
          "type": "User",
          "login": "web-flow",
          "commits": 13,
          "avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.897
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "5 out of 5 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/10 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": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 9 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 10,
            "reason": "all dependencies are pinned",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 10,
            "reason": "security policy file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 10,
            "reason": "GitHub workflow tokens follow principle of least privilege",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "40 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "d188773e88e9e78763a4258fb247599255bfdc9c",
        "ran_at": "2026-08-05T20:54:44Z",
        "aggregate_score": 5.1,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": true,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "recent_prs": {
        "merged_7d": 0,
        "decided_7d": 0,
        "merged_30d": 15,
        "authors_30d": 1,
        "decided_30d": 16,
        "sample_size": 56,
        "window_days": 30,
        "sample_exhausted": false,
        "authors_probed_30d": 1,
        "newcomer_merged_30d": 0,
        "bot_prs_excluded_30d": 0,
        "newcomer_authors_30d": 0,
        "newcomer_decided_30d": 0
      },
      "ci_last_run_at": "2026-07-25T23:01:38Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-25T18:07:41Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 81,
          "created_at": "2026-07-25T22:58:07Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/n1byn1kt/apitap",
    "host": "github.com",
    "name": "apitap",
    "owner": "n1byn1kt"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "good",
      "name": "Overall health",
      "note": "The weighted overall 65 is calibrated to 75 on the published index scale (record calibration 2026-08-02).",
      "notes": [
        {
          "code": "overall_calibration",
          "params": {
            "raw": 65,
            "calibrated": 75,
            "calibration": "2026-08-02"
          }
        }
      ],
      "value": 75,
      "inputs": {
        "security": 59,
        "vitality": 79,
        "community": 60,
        "governance": 48,
        "calibration": "2026-08-02",
        "engineering": 81,
        "ai_readiness": 69,
        "weighted_overall_raw": 65
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 79,
        "weight": 0.21,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "commits_last_year": 374,
              "human_commit_share": 1,
              "days_since_last_push": 10,
              "active_weeks_last_year": 12
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 10 days ago",
                "points": 28.8,
                "status": "partial",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 10
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "12/52 weeks with commits",
                "points": 8.3,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 12
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "374 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 374
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 9 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "exceptional",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 64,
              "latest_release_tag": "v2.2.3",
              "releases_from_tags": false,
              "days_since_latest_release": 10,
              "mean_days_between_releases": 0.7
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "64 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 64
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 10 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 10
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.7 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.7
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "exceptional",
            "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": "moderate",
        "name": "Community & Adoption",
        "value": 60,
        "weight": 0.17,
        "metrics": [
          {
            "key": "popularity",
            "band": "weak",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 41,
            "inputs": {
              "forks": 9,
              "stars": 123,
              "watchers": 1,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "123 stars",
                "points": 33.8,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 123
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "9 forks",
                "points": 7.5,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 9
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "1 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "excellent",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "readme_badges": 3,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": true,
              "readme_badge_services": [
                "shields.io"
              ],
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (Apache-2.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "Apache-2.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 13.5,
                "status": "met",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 55,
            "inputs": {
              "packages": [
                "@apitap/core"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 2030
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "2,030 downloads/month across npm",
                "points": 44.1,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 2030,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "weak",
        "name": "Sustainability & Governance",
        "value": 48,
        "weight": 0.23,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 14,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.897
            },
            "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 90% of commits",
                "points": 2.3,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 90
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Newcomer PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "newcomer_pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 78,
            "inputs": {
              "merged_prs": 52,
              "open_issues": 1,
              "closed_issues": 22,
              "prs_merged_7d": 0,
              "prs_decided_7d": 0,
              "prs_merged_30d": 15,
              "prs_decided_30d": 16,
              "issue_closed_ratio": 0.957,
              "closed_unmerged_prs": 4,
              "first_time_authors_30d": 0,
              "first_time_prs_merged_30d": 0,
              "first_time_prs_decided_30d": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "96% of issues closed",
                "points": 40.2,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 96
                    }
                  }
                ],
                "max_points": 42
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "52/56 decided PRs merged",
                "points": 27.9,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 52,
                      "decided": 56
                    }
                  }
                ],
                "max_points": 30
              },
              {
                "key": "newcomer_pr_acceptance",
                "name": "Newcomer PR acceptance",
                "detail": "no first-time contributor's PR decided in 30d",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_newcomer_prs",
                    "params": {
                      "days": 30
                    }
                  }
                ],
                "max_points": 13
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/10 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "critical",
            "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": 19,
            "inputs": {
              "followers": 0,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "n1byn1kt",
              "public_repos": 2,
              "account_age_days": 269
            },
            "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": "0 followers of n1byn1kt",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "n1byn1kt"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "2 public repos, account ~0 yr old",
                "points": 4.9,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 2
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "exceptional",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "@apitap/core"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 11
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 11 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 11
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "66 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 66
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "excellent",
        "name": "Engineering Quality",
        "value": 81,
        "weight": 0.19,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "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": "5 out of 5 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "exceptional",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "topics": [
                "ai-agent",
                "api",
                "browser-automation",
                "mcp",
                "mcp-server",
                "playwright",
                "web-scraping",
                "skill-file"
              ],
              "has_wiki": true,
              "homepage": "https://www.apitap.io",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://www.apitap.io",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "8 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 8
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 59,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 51,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 5.1
            },
            "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": "5 out of 5 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/10 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 detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 9 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "all dependencies are pinned",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "GitHub workflow tokens follow principle of least privilege",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "40 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Matched the npm:@apitap/core@2.2.2 runtime dependency closure — what installing the published package pulls in — 100 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:@apitap/core@2.2.2",
                  "assessed": 100
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 89,
            "inputs": {
              "source": "osv",
              "advisories": 1,
              "affected_packages": 1,
              "assessed_packages": 100,
              "unassessed_packages": 0,
              "affected_by_severity": "moderate 1",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "1 affected: hono 4.12.33 (moderate 5.3)",
                "points": 14.4,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_affected",
                    "params": {
                      "count": 1,
                      "packages": "hono 4.12.33 (moderate 5.3)"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory has been public longer than 90 days",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "advisories_none_stale",
                    "params": {
                      "days": 90
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "exceptional",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 100,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 69,
        "weight": 0.04,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.9,
              "agent_instruction_files": [
                ".github/copilot-instructions.md",
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 6841
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": ".github/copilot-instructions.md, CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".github/copilot-instructions.md, CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "90 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 90,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 63,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "extension/tsconfig.json",
                "tsconfig.json"
              ],
              "agent_commit_share": 0.45,
              "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": "extension/tsconfig.json, tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "extension/tsconfig.json, tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "45 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 45,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "all dependencies are pinned",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "exceptional",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 101477,
              "source_files_sampled": 285,
              "oversized_source_files": 1
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "1/285 source files over 60KB",
                "points": 54.8,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 285,
                      "oversized": 1
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 20,
            "inputs": {
              "example_dirs": [],
              "has_mcp_signal": true,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? Carries a deliberately small weight: agent tooling is a real maintenance signal, but its absence must never gate the top of the scale (calibration saturates at raw 91, so 100/100 remains reachable with AI Readiness at zero)."
      }
    ],
    "classification": {
      "top": [
        "library",
        "application"
      ],
      "labels": [
        "library",
        "cli",
        "mcp-server"
      ],
      "scores": {
        "cli": 12,
        "library": 16,
        "mcp-server": 11
      },
      "primary": "library",
      "evidence": [
        {
          "tier": "declared",
          "label": "cli",
          "source": "npm.bin",
          "weight": 10
        },
        {
          "tier": "declared",
          "label": "library",
          "source": "npm.entry",
          "weight": 8
        },
        {
          "tier": "distribution",
          "label": "library",
          "source": "registry:npm",
          "weight": 6
        },
        {
          "tier": "dependencies",
          "label": "mcp-server",
          "source": "dep:@modelcontextprotocol/sdk",
          "weight": 4
        },
        {
          "tier": "structure",
          "label": "mcp-server",
          "source": "mcp_signal",
          "weight": 3
        },
        {
          "tier": "description",
          "label": "cli",
          "source": "description:cli",
          "weight": 2
        },
        {
          "tier": "description",
          "label": "library",
          "source": "description:library",
          "weight": 2
        },
        {
          "tier": "description",
          "label": "mcp-server",
          "source": "description:mcp-server",
          "weight": 2
        },
        {
          "tier": "tags",
          "label": "mcp-server",
          "source": "tag:mcp-server",
          "weight": 2
        }
      ],
      "artifacts": [
        {
          "path": "extension/package.json",
          "labels": [
            "library"
          ],
          "ecosystem": "npm"
        },
        {
          "path": "package.json",
          "labels": [
            "cli",
            "library"
          ],
          "ecosystem": "npm"
        }
      ],
      "confidence": "high",
      "host_extension": false,
      "runs_as_process": true,
      "consumed_by_code": true
    },
    "metrics_version": "2.5.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "npm package 'extension' points at a different repository (https://github.com/extension-js/extension.js); excluded from ecosystem scoring",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-08-05T20:54:57.393838Z",
  "schema_version": "0.31.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/n/n1byn1kt/apitap.svg",
  "full_name": "n1byn1kt/apitap",
  "license_state": "standard",
  "license_spdx": "Apache-2.0"
}

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 v2.5.0, esquema v0.31.0 — metodología completa · wiki de métricas.

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