Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 1.13.0 · 2026-07-30 01:21 UTC

ytspar / devbar

Development tools: DevBar and Sweetlink

TypeScriptMIT★ 1 estrella⑂ 0 forksdesde ene 2026Ver en GitHub ↗

ytspar/devbar tiene un índice de salud de 55 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es AI Readiness (83/100) y la más baja, Community & Adoption (36/100). Se actualizó por última vez hace 8 días. Una sola persona concentra la mayor parte del trabajo reciente.

55
global / 100
Moderado

Índice de salud del software

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

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

Perfil de puntuación

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

Titularidad

Yury TsukermanCuenta personal
36 seguidores20 repositorios públicosdesde ago 2010Build Remote

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

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicaciónEtiquetas
npm@ytspar/devbar1.18.35712150hace 12 díasdevelopmentdebugdevbarsweetlinkvanilla-js
npm@ytspar/sweetlink1.27.111.733141hace 1 díaautonomous-developmentai-agentsscreenshotwebsocketchrome-devtools-protocoldevelopment-toolsdebuggingvanilla-js

Métricas por categoría

Vitalidad

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

82Bueno · 22% del índice global
Cómo se puntúa
28.8/36Recencia de push — último push hace 8 días
13.2/36Cadencia de commits — 19/52 semanas con commits
18/18Volumen de commits — 266 commits en el último año
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Datos de entrada utilizados
commits_last_year266
human_commit_share0,94
days_since_last_push8
active_weeks_last_year19
Cómo se puntúa
27/27Publica versiones — 33 versiones publicadas
36/36Recencia de las versiones — última versión hace 8 días
27/27Cadencia de publicación — una versión cada ~4,8 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count33
latest_release_tagsweetlink-v1.27.0
releases_from_tagsno
days_since_latest_release8
mean_days_between_releases4,8
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?

36En riesgo · 18% del índice global
Cómo se puntúa
0/60Estrellas — 1 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars1
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (MIT)
0/18Guía CONTRIBUTING
0/13.5Código de conducta
0/7.2Plantilla de issues
0/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno
Cómo se puntúa
56.6/80Descargas mensuales — 17.445 descargas/mes en npm
0/20Dependientes en el registro — no lo informa este ecosistema
Datos de entrada utilizados
packages@ytspar/devbar, @ytspar/sweetlink
dependents
ecosystemsnpm
total_downloads
monthly_downloads17.445
Excluidos de la puntuación (sin datos o no aplicable): Dependientes en el registro. Los pesos restantes se han renormalizado.

Sostenibilidad y Gobernanza

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

48En riesgo · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
0/22.5Distribución de commits — el principal contribuyente firma el 100% de los commits
1.4/13.5Amplitud de contribuyentes — 1 contribuyentes
6/10OpenSSF Scorecard: Contributors — project has 2 contributing companies or organizations -- score normalized to 6
Datos de entrada utilizados
bus_factor1
contributors_sampled1
top_contributor_share1
Cómo se puntúa
0/46.8Resolución de issues — 0% de issues cerradas
37.2/38.3Aceptación de PR — 34/35 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/24 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs34
open_issues2
closed_issues0
issue_closed_ratio0
closed_unmerged_prs1
Cómo se puntúa
10/30Respaldo de la propiedad — cuenta personal (usuario)
0/20Dominio verificado — no aplicable a cuentas de usuario
11.3/25Alcance del propietario — 36 seguidores de ytspar
21.6/25Trayectoria — 20 repos públicos, cuenta de ~15 años
Datos de entrada utilizados
followers36
owner_typeUser
is_verified
owner_loginytspar
public_repos20
account_age_days5826
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 — 2 paquete(s) en npm
35/35Recencia de publicación — última publicación hace 1 días
20/20Historial de versiones — 150 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packages@ytspar/devbar, @ytspar/sweetlink
ecosystemsnpm
any_deprecatedno
min_days_since_publish1

Calidad de Ingeniería

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

57Moderado · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 4 flujo(s) de trabajo
24/24Pruebas presentes
16/16Configuración de linter — biome.json
0/9.6Hooks de pre-commit
0/6.4.editorconfig
4/20OpenSSF Scorecard: CI-Tests — 5 out of 23 merged PRs checked by a CI test -- score normalized to 2
Datos de entrada utilizados
has_ci
has_tests
has_editorconfigno
has_linter_config
has_precommit_configno

Documentación

40En riesgo
Cómo se puntúa
30/30README
0/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
10/10Descripción del repositorio
0/10Topics
0/10Wiki
Datos de entrada utilizados
topics
has_wikino
homepage
has_readme
has_docs_dirno
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?

46En riesgo · 16% del índice global
Cómo se puntúa
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0.5/2.5CI-Tests — 5 out of 23 merged PRs checked by a CI test -- score normalized to 2
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/24 approved changesets -- score normalized to 0
1.5/2.5Contributors — project has 2 contributing companies or organizations -- score normalized to 6
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 0 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — sin datos
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — sin datos
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 15 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate3,2
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
25/25Dependencias indirectas libres de avisos conocidos — ninguna dependencia indirecta tiene un aviso conocido
0/40Sin avisos pendientes — ningún aviso tiene fecha de publicación
Datos de entrada utilizados
sourceosv
advisories0
affected_packages0
assessed_packages9
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
Excluidos de la puntuación (sin datos o no aplicable): Sin avisos pendientes. Los pesos restantes se han renormalizado. Se cotejó el cierre de dependencias en tiempo de ejecución de npm:@ytspar/devbar@1.18.3 —lo que arrastra la instalación del paquete publicado—: 9 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? Es una insignia independiente y experimental — peso 0,0, de modo que se presenta por separado y no afecta a la puntuación de salud global.

83Bueno · 0% del índice global
Cómo se puntúa
45/45Instrucciones para agentes — AGENTS.md, CLAUDE.md
15/15Documentación legible por máquinas (llms.txt) — llms.txt presente
40/40Historial de commits legible — 78 de 94 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txt
legible_history_share0,83
agent_instruction_filesAGENTS.md, CLAUDE.md
agent_instruction_max_bytes7449
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
11/11Configuración de lint / formato — biome.json
11/11Verificación estática de tipos — packages/devbar/tsconfig.json, packages/playground/tsconfig.json, packages/sweetlink/tsconfig.json, tsconfig.json
10/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 54 de los últimos 100 commits con autoría o crédito de agente
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Datos de entrada utilizados
has_nixno
has_tests
lockfilespnpm-lock.yaml
has_dockerfileno
typed_language
bootstrap_files
has_devcontainerno
has_linter_config
typecheck_configspackages/devbar/tsconfig.json, packages/playground/tsconfig.json, packages/sweetlink/tsconfig.json, tsconfig.json
agent_commit_share0,54
toolchain_manifests
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — TypeScript (tipado estático)
54.4/55Tamaños de archivo manejables — 3/271 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageTypeScript
largest_source_bytes163.647
source_files_sampled271
oversized_source_files3

Datos clave

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

Advertencias de recopilación de datos

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Más detalle

OpenSSF Scorecard 3.2 / 10
3.2agregado

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

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
2CI-Tests5 out of 23 merged PRs checked by a CI test -- score normalized to 2
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/24 approved changesets -- score normalized to 0
6Contributorsproject has 2 contributing companies or organizations -- score normalized to 6
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
n/dPackagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities15 existing vulnerabilities detected
Dependencias directas 7
RegistroPaqueteRestricción de versiónManifiesto
npm@ytspar/sweetlinkworkspace:^packages/devbar/package.json
npmaxe-core^4.10.2packages/devbar/package.json
npmhtml2canvas-pro^2.0.0packages/devbar/package.json
npm@ytspar/devbarworkspace:*packages/playground/package.json
npm@ytspar/sweetlinkworkspace:*packages/playground/package.json
npmdotenv^17.2.4packages/sweetlink/package.json
npmws^8.18.3packages/sweetlink/package.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 0

Instalar npm:@ytspar/devbar@1.18.3 arrastra 9 paquetes, directos y transitivos: 0 tienen avisos conocidos, de los cuales 0 son dependencias directas.

Ningún aviso conocido afecta a las dependencias evaluadas.

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": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 4298,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "CSS": 50853,
        "HTML": 5219,
        "Shell": 4319,
        "JavaScript": 187310,
        "TypeScript": 2426017
      },
      "pushed_at": "2026-07-21T16:09:58Z",
      "created_at": "2026-01-28T12:00:20Z",
      "owner_type": "User",
      "updated_at": "2026-07-21T14:41:38Z",
      "description": "Development tools: DevBar and Sweetlink",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Yury Tsukerman",
      "type": "User",
      "login": "ytspar",
      "company": "Build Remote",
      "location": null,
      "followers": 36,
      "avatar_url": "https://avatars.githubusercontent.com/u/365593?v=4",
      "created_at": "2010-08-16T06:37:49Z",
      "is_verified": null,
      "public_repos": 20,
      "account_age_days": 5826
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "sweetlink-v1.27.0",
          "kind": "other",
          "published_at": "2026-07-21T14:38:05Z"
        },
        {
          "tag": "devbar-v1.18.3",
          "kind": "other",
          "published_at": "2026-07-17T19:09:37Z"
        },
        {
          "tag": "sweetlink-v1.26.4",
          "kind": "other",
          "published_at": "2026-07-17T10:36:08Z"
        },
        {
          "tag": "devbar-v1.18.1",
          "kind": "other",
          "published_at": "2026-07-06T07:04:16Z"
        },
        {
          "tag": "sweetlink-v1.26.3",
          "kind": "other",
          "published_at": "2026-07-06T07:02:45Z"
        },
        {
          "tag": "sweetlink-v1.26.0",
          "kind": "other",
          "published_at": "2026-06-25T06:22:30Z"
        },
        {
          "tag": "sweetlink-v1.25.0",
          "kind": "other",
          "published_at": "2026-06-23T17:08:45Z"
        },
        {
          "tag": "sweetlink-v1.24.6",
          "kind": "other",
          "published_at": "2026-06-19T12:08:56Z"
        },
        {
          "tag": "sweetlink-v1.24.5",
          "kind": "other",
          "published_at": "2026-06-19T10:56:49Z"
        },
        {
          "tag": "devbar-v1.18.0",
          "kind": "other",
          "published_at": "2026-06-08T15:19:25Z"
        },
        {
          "tag": "devbar-v1.14.3",
          "kind": "other",
          "published_at": "2026-05-06T07:26:41Z"
        },
        {
          "tag": "devbar-v1.14.2",
          "kind": "other",
          "published_at": "2026-05-06T07:18:17Z"
        },
        {
          "tag": "devbar-v1.14.1",
          "kind": "other",
          "published_at": "2026-05-06T07:08:47Z"
        },
        {
          "tag": "devbar-v1.14.0",
          "kind": "other",
          "published_at": "2026-05-06T06:42:07Z"
        },
        {
          "tag": "devbar-v1.10.6",
          "kind": "other",
          "published_at": "2026-04-27T06:37:40Z"
        },
        {
          "tag": "sweetlink-v1.21.0",
          "kind": "other",
          "published_at": "2026-04-27T06:37:39Z"
        },
        {
          "tag": "devbar-v1.10.5",
          "kind": "other",
          "published_at": "2026-04-27T03:42:35Z"
        },
        {
          "tag": "sweetlink-v1.20.0",
          "kind": "other",
          "published_at": "2026-04-27T03:42:34Z"
        },
        {
          "tag": "devbar-v1.10.4",
          "kind": "other",
          "published_at": "2026-04-27T02:53:21Z"
        },
        {
          "tag": "sweetlink-v1.19.0",
          "kind": "other",
          "published_at": "2026-04-27T02:53:20Z"
        },
        {
          "tag": "devbar-v1.10.3",
          "kind": "other",
          "published_at": "2026-04-26T15:44:54Z"
        },
        {
          "tag": "sweetlink-v1.18.0",
          "kind": "other",
          "published_at": "2026-04-26T15:44:52Z"
        },
        {
          "tag": "devbar-v1.10.2",
          "kind": "other",
          "published_at": "2026-04-26T15:44:51Z"
        },
        {
          "tag": "sweetlink-v1.17.0",
          "kind": "other",
          "published_at": "2026-04-26T15:44:50Z"
        },
        {
          "tag": "v1.15.0",
          "kind": "minor",
          "published_at": "2026-03-26T20:11:56Z"
        },
        {
          "tag": "devbar-v1.4.0",
          "kind": "other",
          "published_at": "2026-02-12T13:44:05Z"
        },
        {
          "tag": "sweetlink-v1.3.0",
          "kind": "other",
          "published_at": "2026-02-12T13:43:52Z"
        },
        {
          "tag": "devbar-v1.3.0",
          "kind": "other",
          "published_at": "2026-02-11T18:20:49Z"
        },
        {
          "tag": "sweetlink-v1.2.0",
          "kind": "other",
          "published_at": "2026-02-11T18:20:43Z"
        },
        {
          "tag": "devbar-v1.2.0",
          "kind": "other",
          "published_at": "2026-02-11T17:02:36Z"
        },
        {
          "tag": "devbar-v1.1.0",
          "kind": "other",
          "published_at": "2026-02-11T17:02:34Z"
        },
        {
          "tag": "sweetlink-v1.1.0",
          "kind": "other",
          "published_at": "2026-02-11T17:02:31Z"
        },
        {
          "tag": "v1.0.0",
          "kind": "major",
          "published_at": "2026-02-09T18:23:34Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "48cfa865e8c224fccf426d5bc3510d64a1487c25",
          "body": "* chore(main): release sweetlink 1.27.0\n\n* chore(sweetlink): re-key the release note to 1.27.0\n\nThe batch-mode feat rolled the pending release from 1.26.5 to a minor, so the\nnote has to move with it or the release-notes gate blocks the PR. Folded the\nbatch-mode measurements into the same entry.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(main): release sweetlink 1.27.0 (#37)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-21T14:37:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c1fb107d5ff30e46b628c256797526cb4692ac5b",
          "body": "Once the daemon fix removed the per-frame browser launch, the dominant cost\nbecame Node startup and module load — paid once per frame because every caller\ndrove captures as a shell loop of separate CLI invocations.\n\n`screenshot --batch <manifest.json|->` takes the whole frame list up front and\ncaptu\n[…]\nit would make every frame overwrite the last, and a directory of\nidentical frames reads downstream as a capture bug rather than a bad manifest.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): add --batch to capture many frames in one process",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-21T10:03:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "51054c50fbb1bdea306321e24df03e27db0334f0",
          "body": "Two defects that together made automated capture slow, and its output\nunreviewable.\n\n**Every headless capture cold-launched a browser.** The persistent daemon was\ngated behind `--hifi`/`--responsive`, so the automated callers — visual-evidence\ngallery frames, batch capture runs — never reached it an\n[…]\n Pages rendered without devbar never host one; the message\ndescribed a fault that isn't one and named an engine that is no longer the\none used.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(sweetlink): reuse the daemon browser and honour Portless URLs",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-21T08:11:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9a39d3788dabe5279d2d45de3e14ec9f99b4461a",
          "body": "* chore(main): release devbar 1.18.3\n\n* docs(devbar): add 1.18.3 release note for the release-notes gate\n\nThe DEV-6497 quiescent-capture badge-hide fix (#35) shipped without its\nplayground release-notes.json entry, so the Release PR's release-notes\ngate failed. Add the 1.18.3 note so the gate passes and the publish runs.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(main): release devbar 1.18.3 (#36)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-17T19:09:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fc8bb93f6ed1503c48a9bbd43deb85e413153cd8",
          "body": "`suppressFrameworkDevIndicators` dropped the shadow-root style injection\nwhen the `nextjs-portal` element was present but its shadow root had not\nattached yet. The light-DOM MutationObserver sees the portal insertion\n(shadow still null) but never the later shadow attach — that's a shadow-DOM\nmutatio\n[…]\ndy, then\ngive up so a never-attaching portal can't spin forever. Adds a regression\ntest where the shadow root attaches after the portal mounts.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(devbar): retry badge-hide injection for quiescent captures (#35)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-17T18:18:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "01cbd39a6d2f259bc0cec41ebd487c703c6aa455",
          "body": "…5) (#34)\n\nThe DEV-6469 guard printed the tag to re-push using the single top-level\n`tag_name` output. This repo is a manifest (multi-package) release-please\nsetup, where that output is usually empty — the tags live in per-path\noutputs (`packages/devbar--tag_name`, …). So the recovery instruction fe\n[…]\nsteps.release.outputs)` via jq, list\nall released tags, and emit a per-tag re-push loop. Keeps the single\n`tag_name` and placeholder fallbacks.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(release): list every released tag in the no-publish guard (DEV-649…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-17T18:17:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3049085e27ee1e16731a17b410f18ab0e16e9ae5",
          "body": "… (#33)\n\nA release-please tag created with the fallback GITHUB_TOKEN cannot trigger\nrelease.yml — GitHub mutes workflow triggers on refs pushed with\nGITHUB_TOKEN — so when RELEASE_PLEASE_TOKEN is unset the npm publish\nsilently never runs and the version is tagged-but-unpublished. That's how\ndevbar 1\n[…]\n\n(re-push the tag from a real credential). When the PAT is present it\npasses silently. Converts a silent no-publish into an unmissable red run.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(release): fail loudly when a release can't auto-publish (DEV-6469)…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-17T16:57:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4ce531f78b0537c41d28888ffe325ae0e87cca58",
          "body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(main): release devbar 1.18.2 (#32)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-17T13:31:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c3c3591a3b1999057951a32fef31583297e80b4c",
          "body": "The Next.js dev-tools indicator (the floating \"N\" badge) renders inside a\n`nextjs-portal` shadow root, fixed to a bottom corner. At rest it\nduplicates the devbar, sits on top of page content, and pollutes\nscreenshots — and shadow-DOM encapsulation means no capture pipeline can\nhide it from the outsi\n[…]\n `[data-nextjs-dialog-overlay]`\nerror overlay) stay fully visible. `data-error` is live, so the CSS\nreacts on its own. Disposed on `destroy()`.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(devbar): hide the benign Next.js dev-tools badge from captures (#28)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-17T12:07:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7e594ad253ead60b665fd4e118cef3dd1b9baed5",
          "body": "* chore(main): release sweetlink 1.26.4\n\n* docs: release note for sweetlink 1.26.4\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>\nCo-authored-by: Yury Tsukerman <ytspar@yandex.com>\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": true,
          "headline": "chore(main): release sweetlink 1.26.4 (#31)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-17T10:35:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f3e7a558dbdd79da14fede397797990fd7e20a79",
          "body": "… (#30)\n\nThe two self-contained review UIs could let a wider-than-container\nimage escape its box:\n\n- viewer.ts: the video/screenshot is a flex item whose default\n  min-width:auto can refuse to shrink below the media's intrinsic\n  width despite max-width:100%. Add min-width:0; min-height:0 so it\n  ac\n[…]\nuto to img for aspect ratio when\n  clamped; and make figure min-width min(300px,100%) so narrow\n  viewports don't force horizontal page scroll.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(sweetlink): keep wide images/video inside the HTML review viewers…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-17T10:32:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "06492d0d547b46ec30485455a07526e7f82f3a5d",
          "body": "The release-please PR for 1.26.3 merged without its hand-written playground\nnote, so the publish workflow's 'Validate release notes' step fails and\n1.26.3 is tagged but unpublished. Same gap class as verticalint DEV-5362.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: release note for sweetlink 1.26.3",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-16T09:32:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7703e8ba2f92a50baaf513b0ebc4f9e3e65849dd",
          "body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(main): release devbar 1.18.1 (#27)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-06T07:04:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "66f78a483e5bd2198672d97dd078193ca301a34a",
          "body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(main): release sweetlink 1.26.3 (#26)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-06T07:02:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b47fc34aae616e1ebad9a6e6e9912f8393a7c88",
          "body": "…#25)\n\n* fix(sweetlink): resolve agent-bridge WS endpoint correctly under HTTPS proxies\n\nRepro: Next.js 16 (Turbopack) app behind a Portless HTTPS proxy\n(https://places.localhost → app port 4836, sweetlink WS on 11059).\nThe browser client derived the WS port from location.port (443) + 6223\n= 6666 an\n[…]\nt-of-bounds errors preserved; explicit\nselector paths locked to old behavior.\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": "fix: agent bridge under HTTPS proxies + daemon navigation/lifecycle (…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-05T18:07:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e99e38c62f1ce43e676a2f96be4305075b80445b",
          "body": "Adds the missing release note that blocked the 1.26.2 publish (the\nprepublishOnly check-release-notes gate, #22, requires an entry). Note\ncovers the opacity:0 devbar-hide fix (#24).",
          "is_bot": false,
          "headline": "docs: release note for sweetlink 1.26.2",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-03T05:39:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e7dd12aff4f5e26647126f715b33765fc064a633",
          "body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(main): release sweetlink 1.26.2 (#23)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-02T22:28:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5003bb4187d130888bd79825fdb301b3c9eb2827",
          "body": "…eak (#24)\n\nThe screenshot devbar-hide injected `visibility: hidden !important` on\n`[data-devbar]`. That's escaped when the devbar is EXPANDED: its toolbar\nbuttons/icons are descendants that set their own `visibility`, so a\ncontainer-level `visibility: hidden` doesn't cover them and the bar leaks\nin\n[…]\n`nextjs-portal` (which also hosts the error\noverlay we want captured).\n\nVerified end-to-end: el-visual-evidence /finances capture is now free of the\ndevbar and query-devtools overlays. Tests extended.",
          "is_bot": false,
          "headline": "fix(sweetlink): hide devbar with opacity:0 so an expanded bar can't l…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-02T22:28:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0a1121a05c231c9d96566b28d5cb3d6fe2ef92e6",
          "body": "… guard (#22)\n\nrelease-please bumps package versions but never writes the hand-maintained\npackages/playground/src/release-notes.json entry that check-release-notes.mjs\nrequires at publish time — so the first automated publish (sweetlink 1.26.1)\nfailed twice, after merge, when the author had moved on\n[…]\nad of stripping\n  the suffix and still requiring the base version's note. Canaries publish\n  not-yet-released versions; the note is authored later on the Release PR.\n  Production versions stay strict.",
          "is_bot": false,
          "headline": "ci: gate release PRs on release notes; exempt canaries from the notes…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-02T15:21:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "960fe0bd793f1a7c6a0f282f893a2e50470ff289",
          "body": "The release-notes prepublish guard blocked the first release-please\npublish (canary run 28593594496): release-please bumps versions but\ndoes not write release-notes.json entries — a template integration gap\nto note in the runbook. Entry added for the resize-for-claude skill fix\n(DEV-5303).",
          "is_bot": false,
          "headline": "docs: release note for sweetlink 1.26.1",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-02T13:41:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8fd5566402023d15865416a092465d8311591cb9",
          "body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "chore(main): release sweetlink 1.26.1 (#21)",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-02T13:25:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "489eb5253f747630aec07084024f82d2750ebaab",
          "body": "* feat: add release-please automation for both packages\n\nOn merge to main, release-please opens per-package Release PRs\n(conventional commits -> version + CHANGELOG); merging one creates the\npackage's sweetlink-vX.Y.Z / devbar-vX.Y.Z tag (existing scheme) and a\nGitHub release, and the tag triggers t\n[…]\n.0 lets release-please\ncorrectly capture and ship the pending delta. Also documents that the\nmanual production dispatch is emergency-only and desyncs the manifest\nunless it's bumped by hand afterward.",
          "is_bot": false,
          "headline": "feat: add release-please automation for both packages (#20)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-02T10:30:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dd3c1f1de99170fe28eda9af7c2c0bad2bfe2e71",
          "body": "* fix(sweetlink): bundle resize-for-claude script with its skill\n\nThe skill referenced a script at <tools-repo>/scripts/resize-for-claude\nthat no longer exists anywhere — the tools repo deleted it in its\nDEV-3464 reorg as 'duplicated the skill', but the skill only documented\nit. On top of that, the \n[…]\n prefix\n(npm packing drops the executable bit), clarify downscale-only behavior,\nclear stale -partN tiles on re-run, and fail friendly on non-image input\n(validates sips dimensions before arithmetic).",
          "is_bot": false,
          "headline": "fix(sweetlink): bundle resize-for-claude script with its skill (#19)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-07-02T08:20:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bd4cedf4b27f895108b37e5bd80358d85acda899",
          "body": "…e (#18)\n\nSurface the canonical devbar-hide screenshot rule publicly so downstream\nconsumers (the el-visual-evidence CLI in vertical-int/tools) can import it\ninstead of hand-maintaining a drifting copy.\n\n- Re-export HIDE_DEVBAR_CSS, HIDE_DEVBAR_STYLE_ID, SELECTOR_TIMEOUT_MS,\n  HOVER_TRANSITION_DELAY\n[…]\ne-exports stay in sync.\n- Bump sweetlink to 1.26.0 + release note.\n\nPrereq for vertical-int/tools DEV-4982 (consumes this export).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "DEV-4982: export HIDE_DEVBAR_CSS from @ytspar/sweetlink public surfac…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-25T06:18:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4b31fa62d9ff40a9426a1d9c7018300e530d5a48",
          "body": "The three cycle-1-deferred unit tests for the DEV-4874 hardening fixes\n(landed in #16), as a test-only follow-up:\n\n- recording.test.ts: stopRecording logs the null-video warning + writes a\n  manifest with video undefined when page.video() is null; getRecordingStatus\n  is pause-aware (duration exclud\n[…]\ntarting its own (leak fix), and rolls back the optimistic UI on a\n  success:false response.\n\nTest-only (111/111 in the two files).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "DEV-4893: backfill recorder/devbar hardening tests (#17)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-23T04:10:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "34500460e1b2f02ed89f8158137953743a4e876c",
          "body": "…idence (#16)\n\n* DEV-4874: sweetlink viewer exports + recorder hardening for motion evidence\n\nMake the session-recording output pipeline consumable from outside the\ndaemon, and harden the recorder, so el-visual-evidence can reuse it for\nmotion/video evidence (DEV-4873).\n\nAdditive (sweetlink 1.25.0):\n[…]\nure-rollback (need the devbar DOM-state harness).\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": "DEV-4874: sweetlink viewer exports + recorder hardening for motion ev…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-21T16:27:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "889a040108941ab6d54e86eff84ea70d0c04d1f4",
          "body": "…814) (#15)\n\n`@ytspar/sweetlink@1.24.5` silently dropped\n`claude-skills/resize-for-claude/SKILL.md` from the published tarball —\nonly the `evals/` directory remained. The skill is referenced by\n`tools/claude/skills/figma-design/SKILL.md` as the canonical \"prepare\nimage for Claude vision\" path, so th\n[…]\ntory.\n\nNo source/runtime change. Downstream consumers (tools) can re-add the\n`claude/skills/resize-for-claude -> @ytspar/sweetlink/claude-skills/resize-for-claude`\nsymlink once they upgrade to 1.24.6.",
          "is_bot": false,
          "headline": "fix(sweetlink): bump 1.24.6 to ship resize-for-claude/SKILL.md (DEV-4…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-19T12:07:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8582affb192fbdfa66af3e2896332ed3d1f413ef",
          "body": null,
          "is_bot": false,
          "headline": "docs(sweetlink): add Claude skill examples",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-19T11:02:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "765d8f8ee091e34f3f5146e105aaa58e75853a73",
          "body": null,
          "is_bot": false,
          "headline": "ci: repair npm trusted publishing workflow",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-19T10:53:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "464a4f4d0f6e557f6dc5d1648e39b7416a9b529d",
          "body": "…) (#13)\n\n* refactor(sweetlink): dedupe Claude-skill prose, bump 1.24.5 (DEV-4697)\n\nThe three Sweetlink-driven Claude skills (screenshot, console-check-sweetlink,\nresponsive-screenshots) each carried their own copy of the Sweetlink\narchitecture / prerequisites / CLI surface / daemon lifecycle prose \n[…]\nmanual skill re-sync needed.\n\nNo behavior change.\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": "refactor(sweetlink): dedupe Claude-skill prose, bump 1.24.5 (DEV-4697…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-18T23:05:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7a72e7a29e8601bbeb371187db0b32aeaa1db1cc",
          "body": "…nore (DEV-4726) (#14)\n\nThe bare `claude-skills/` rule was intended to ignore consumer-project\nsymlinks to the published @ytspar/sweetlink package, but was also\nmatching the source-of-truth directory inside packages/sweetlink/.\nOnly screenshot/SKILL.md was tracked (force-added long ago); the other\nt\n[…]\nde}/SKILL.md → NOT ignored\n- tools/.claude/skills/screenshot/SKILL.md → still ignored\n- top-level claude-skills/foo/SKILL.md → still ignored\n- packages/other/claude-skills/foo/SKILL.md → still ignored",
          "is_bot": false,
          "headline": "chore(devbar): carve out packages/sweetlink/claude-skills/ from gitig…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-18T21:12:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2e7bf4757c8e24cb05c578000da9cf1af086f254",
          "body": "…EV-4521) (#12)\n\nThe Sweetlink WebSocket has no origin/auth model, so honoring `exec-js`\nunconditionally was an unauthenticated RCE: any local process — or any web page\nthat can reach `ws://localhost:<port>` (WebSocket connections aren't gated by\nsame-origin policy) — could execute arbitrary JS in t\n[…]\n #10\nmerges. A full out-of-band nonce/secret handshake (so trusted callers don't need\nthe blanket opt-in) is a future enhancement.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(devbar): exec-js OFF by default — close unauthenticated WS RCE (D…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-06T17:14:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4161e1c7b653f8a29934005ff438f3faf7d1b812",
          "body": "Safe, high-value fixes surfaced by a 3-agent deep review.\n\nBundle (~790KB off the eager browser bundle):\n- build-browser.mjs now uses esbuild code-splitting so axe-core + html2canvas-pro\n  (already lazy-import()ed in source) are emitted as on-demand chunks instead of\n  inlined. Eager entry ~992KB → \n[…]\nbmit/empty-guard),\nEsc-resync regression, and initGlobalDevBar annotate wiring. Full suite green\n(1146 devbar tests), build clean.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(devbar): hardening + optimization round (DEV-4520) (#10)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-06T16:56:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "71ad8e3d47cf4dd2b5a677a3f7116ca83ecfc7d4",
          "body": null,
          "is_bot": false,
          "headline": "fix(devbar): keep inline release badges content-sized (#7)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-06T04:43:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3ecdf44b91991a329daa7828259e0ddc12f7152b",
          "body": "…24.4) (#8)\n\nVisual evidence must show the change IN CONTEXT in the running app —\ncomponent-library/gallery views are a secondary source. Scale coverage to\nthe change: in-context page capture; per-state frames for interactive\nelements; all-path frames for multi-step/branching elements; a process\nsto\n[…]\n) and durable, CI-runnable specs\ncommitted to the e2e suite.\n\nGeneralizable principle; downstream projects enforce it in their own\nCLAUDE.md / skills (e.g. Enrich Layer's el-visual-evidence workflow).",
          "is_bot": false,
          "headline": "docs(sweetlink): add Coverage section to UI Verification Mandate (v1.…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-06T04:26:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "74b5780f28958e983c67aa647468d35c76d34d22",
          "body": "Adds an \"Annotate\" toolbar control — the in-context, live-page companion to the\nel-visual-evidence standalone review UI. Click an element on the running page to\npin a region comment (fix/question/praise); the pin POSTs to the\n`el-visual-evidence review-ui --listen` server and lands in the same\nfeedb\n[…]\nviewport/submit/lifecycle/control-toggle). Full suite\n  green (2445 tests, no regression). Version 1.15.1 → 1.16.0 + release note.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(devbar): live visual-feedback Annotate control (DEV-4516) (#9)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-06-06T04:26:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3925fe077cd2226a0b3a177d3e24bf1a9d26d32d",
          "body": "1.15.0 shipped with stale dist/ from before the source edits, so the\nautoConnect option had a version bump but no runtime/type behavior. This\nrelease ships the same source built fresh. 1.15.0 will be deprecated on\nthe registry with a redirect message.\n\nAlso: add `.npmrc.publish` to .gitignore (used as an ad-hoc auth file\nfor local publish runs; should never be committed).",
          "is_bot": false,
          "headline": "chore(release): devbar 1.15.1 — rebuild with proper dist (#6)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-11T10:16:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0683e07c93bd162aa0d9a3b2438e19c0171081d0",
          "body": "New `sweetlink.autoConnect` option (default `true`). When set to `false`,\nthe initial WebSocket connect from setup is skipped — for projects that\nload devbar but don't run the Sweetlink CLI, where the browser's\nunsuppressible `WebSocket connection to 'ws://...' failed: ECONNREFUSED`\non every page lo\n[…]\nl opt in at runtime via\n`globalDevBar.connectWebSocket()`.\n\nNo behavior change for existing setups (autoConnect defaults to true).\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(devbar): sweetlink.autoConnect option to silence WS noise (#5)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-11T08:37:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a00fef35614f9d2566971bee5a647b4d293e2685",
          "body": null,
          "is_bot": false,
          "headline": "Fix modal clipboard copying",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-09T19:28:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ceb819cd25c006f906746d0849faf4e64fd3b9bf",
          "body": null,
          "is_bot": false,
          "headline": "Default devbar to compact on small screens",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-09T16:51:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8702c881d486fadb93cdba0b0a1c9bacd99dc657",
          "body": null,
          "is_bot": false,
          "headline": "Fix devbar custom controls spacing",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-09T15:27:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da07c30feeae4b194d3413dd4e883ad6a8cc7d28",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): sweetlink 1.24.3 and devbar 1.14.6",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-09T09:11:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "de480c105bf1e4e7a1e2a52cc33fc528bfa41d24",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): devbar 1.14.5",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-09T08:28:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fceb064878fa440a7e598caeb85988cf8d85e4ba",
          "body": null,
          "is_bot": false,
          "headline": "Match tooltip text color to trigger controls",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-09T08:21:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8faca11aaebf014bf1886e39f6a6ab8ad5967409",
          "body": "Widens sweetlink's `vite` peer-dependency range to include `^8.0.0`\n(was `^5 || ^6 || ^7`). Vite 8 is GA and consumers were hitting\npeer-conflict errors on install. devbar bumped so workspace:^\nresolves to the patched sweetlink.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): sweetlink 1.24.1 + devbar 1.14.4",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-06T18:35:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "02b9cca6846017c89ad45bef45d765a7c55159fe",
          "body": null,
          "is_bot": false,
          "headline": "fix(devbar): compact simulated mobile controls",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-06T07:24:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9095c1a2d05490eecad7f6f83ee797bdf3542705",
          "body": null,
          "is_bot": false,
          "headline": "fix(devbar): shrink medium release badge layout",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-06T07:16:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79019025998516240e8484eb4fce9352b6bbc058",
          "body": null,
          "is_bot": false,
          "headline": "fix(devbar): sync themes and tighten release badges",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-06T07:07:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "180c708b57ba34652e8f1f934985e259c564dd71",
          "body": null,
          "is_bot": false,
          "headline": "feat(devbar): add release info plugin",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-06T06:40:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "73a52fd4073d02b7d275a9eb0194a6ef8c295c97",
          "body": "Hardening release rolling up the multi-agent product-finalizer audit work:\n- 5 critical security fixes (path traversal cluster, WS proxy origin-pin,\n  viewer XSS encoder)\n- 10 P1 race/leak fixes (CLI routing FIFO, pendingRequests WeakMap,\n  recording goto rollback, safeRegex alternation guard, daemo\n[…]\ndules\n- vite 7.3.2 override patches dev path-traversal advisory\n\nVerified: pnpm typecheck + 2411/2411 tests + pnpm build all pass.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release: devbar 1.13.0 + sweetlink 1.24.0",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-05T17:21:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "90a6cb7801767e939eb8a46fa46343da07bb0aeb",
          "body": "77 new tests across the modules el-audit flagged as missing tests.\nCombined with the prior TST1 batch, this brings 12 more source files\nunder colocated test coverage. The 11 still-untested files are build\nconfigs (vite/vitest/playwright), entry points (browser.ts/server.ts),\nthe 4000-line daemon/ser\n[…]\nring artifacts)\n  - Pure function — does not mutate process.env\n\nVerified: pnpm typecheck + 2411/2411 tests + pnpm build all pass.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add tests for 12 more modules to close TST2 coverage gap",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-05T17:15:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bf3dfdfcedd083718deede52218546a0351488e3",
          "body": "72 new tests across the modules the audit flagged as load-bearing but\nuntested. Each test covers real behavior and regressions, not vanity\ncoverage.\n\npackages/sweetlink/src/daemon/listeners.test.ts (24 tests):\n  - installListeners is idempotent on the same Page object\n  - Multi-page captures merge i\n[…]\n tests for the\ne2e harness run alongside the rest of the suite.\n\nVerified: pnpm typecheck + 2334/2334 tests + pnpm build all pass.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add tests for 5 critical modules previously without coverage (TST1)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-05T16:53:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a70663e75729c35d22aca409abe99a21ad26174c",
          "body": "Replace 28-case switch in sweetlink.ts with a dispatch via named handler\nfunctions. Each command's logic is now in a standalone async function\nthat can be tested in isolation by importing the handler directly.\n\nThe switch body is now ~70 lines of simple `case 'X': result = await\nhandleXCmd(); break;\n[…]\nCmd\nfunction instead of nested if/else inside the switch.\n\nNo behavior change. Verified: pnpm typecheck + 2262/2262 tests + build.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Extract CLI dispatch into named handlers (Simp #6)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-05T16:45:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "31ec3b80447e4bffb0a17cdab05d8ea53b1fd7b0",
          "body": "Security (adversarial P0/P1/P2):\n- Path traversal: sanitize HMR trigger slug + new confinePath helper for\n  daemon generate-viewer / visual-diff sessionDir/outputPath (P0 #1-3)\n- Origin-pin WS recording/HiFi proxies to the daemon's app port so a\n  malicious page on a different localhost port can't t\n[…]\n deps in dev audit)\n- Delete unreferenced 145KB devbar-anim.gif\n\nVerified: pnpm typecheck + 2262/2262 tests + pnpm build all pass.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Harden security & tighten public-API types from product-finalizer audit",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-05T16:34:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5f2060ebef8505b2eb64c99417881fd96a4c9ad7",
          "body": "Expanded mode hard-coded the wrapper color to CSS_COLORS.primary, so a\ncustom or non-emerald accent produced a mismatched border/text pair\n(e.g. red border with green text). Collapsed and compact layouts\nalready used accentColor; align expanded.\n\nBumps devbar to 1.12.1.",
          "is_bot": false,
          "headline": "Make expanded toolbar text follow the accent color",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-05T06:23:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6564d07ff91f0e13155bdc24f0514b50d99bbd1d",
          "body": "- New `@ytspar/devbar/browser` and `@ytspar/devbar/browser/auto` exports\n  ship pre-bundled, self-contained ESM for no-bundler consumers via an\n  internal esbuild step (added as a devDependency).\n- Settings popover accent picker now highlights Emerald when the\n  persisted accent is the theme-default\n[…]\nd for fresh installs).\n- Custom accent values surface a `custom · reset` pill so users with a\n  non-preset hex can return to the theme default without clearing\n  localStorage.\n\nBumps devbar to 1.12.0.",
          "is_bot": false,
          "headline": "Add browser bundle entry and fix accent picker UX",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-05T05:30:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "45bc8bc198f295f0b2dd23744f8d15ad67ec0313",
          "body": null,
          "is_bot": false,
          "headline": "Make devbar site agent-friendly",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-05-01T18:59:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2da2213ad3f84568e88abed2d01411cc85716434",
          "body": null,
          "is_bot": false,
          "headline": "Pin pnpm version in DevBar workflows",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-29T16:25:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ebca9b55afe55d32b0ab7aad10de896d9749dfd",
          "body": null,
          "is_bot": false,
          "headline": "Update DevBar workflows to Node 24 actions",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-29T16:23:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fbaf7b13dd068d2687acda34ea90e887a44b42d6",
          "body": null,
          "is_bot": false,
          "headline": "Fix DevBar package publish workflows",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-29T16:21:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd47c66f92698a0db84d407f5771b80d3336ab8d",
          "body": null,
          "is_bot": false,
          "headline": "Add DevBar theme mode controls",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-29T16:17:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dde3544ec90515c0e1075ecf7068316a9104b9d3",
          "body": null,
          "is_bot": false,
          "headline": "Add Portless support to devbar",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-29T10:31:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bbefaa496a7b0f0fa792ba8f0daef2cc5b452025",
          "body": null,
          "is_bot": false,
          "headline": "fix: support portless localhost origins",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-28T21:23:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d655ed842f94814f1bd5e5b9ad6b57c767c0470d",
          "body": null,
          "is_bot": false,
          "headline": "feat: auto-hide devbar screenshots and harden demo UI",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-28T08:54:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "39cf846c7fa7372f489245d0595f66c933f6a1d6",
          "body": null,
          "is_bot": false,
          "headline": "Use direct Wrangler deploy for Cloudflare Pages",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-28T05:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b3b1dc2b7113aacea1ab05ba6da8bb4a07446fb4",
          "body": null,
          "is_bot": false,
          "headline": "Fix Cloudflare Pages workflow wrangler install",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-28T05:07:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "16c2f80142d5d81b3a51b1145c481bc412c11237",
          "body": null,
          "is_bot": false,
          "headline": "Add hide-devbar screenshots and Cloudflare Pages deploy",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-28T05:05:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d8ee6af6d733bee11ca953f524eb6873fa0deab",
          "body": null,
          "is_bot": false,
          "headline": "Harden devbar custom plugin layout",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-27T20:26:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4aba23adeb88edb91c317fdcfba1264fea48f111",
          "body": null,
          "is_bot": false,
          "headline": "Harden frontend assistant evidence and mobile UX",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-27T20:07:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "35e9e5cfe962a8251f5051beb2c521f0066afd15",
          "body": null,
          "is_bot": false,
          "headline": "Improve frontend assistant evidence and demo UX",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-27T14:31:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4b6cf2a06da65f904ace0c721f9d938cecc2eddb",
          "body": "Sweetlink 1.21.0 → 1.22.0 (minor); Devbar 1.10.6 → 1.10.7 (patch).\n\nSecurity (P0)\n- term/cast.ts: escapeJsonForScript escapes </script>, <!--, U+2028/U+2029\n  before the JSON.stringify result is interpolated into the player's inline\n  <script> block. Recorded shell output containing those bytes prev\n[…]\ne} — no cleanup needed)\n- E1-E51 (intentional graceful-degradation in CLI/daemon)\n- D1-residual (6 dev-only pnpm advisories above)\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "hardening: audit findings — security, bug class, type design, cleanup",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-27T10:28:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "235fe17b0e018449f71a4c1384b0699f730fe3be",
          "body": "….21.0)\n\nWhile `adb shell screenrecord` captures the screen, a parallel\n`adb shell getevent -l` listener parses BTN_TOUCH DOWN/UP +\nABS_MT_POSITION_X/Y events into (x, y, t) tuples. Coordinates are\nscaled from raw input-device units to screen pixels using a one-off\n`getevent -p` probe (for the input\n[…]\n-overlay/.\n\n2352 unit + 82/85 e2e tests pass (3 skipped: platform-conditional sim).\n\ndevbar 1.10.6 is a workspace re-resolve bump.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): Android tap-indicator overlays for sim recordings (1…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-27T06:36:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9638bc8788202a2a4aab4500b82095264998aa9a",
          "body": "Two more `proof`-parity items.\n\n**Multi-capture JSON-stdin batch mode.**\n`cat captures.json | sweetlink --json` reads\n  { action: \"capture\", captures: [...] }\nfrom stdin and runs each entry sequentially, aggregating results into\na single envelope on stdout:\n  { ok, duration, captures: [{ ok, mode, l\n[…]\n83 e2e + 2334/2334 unit tests pass (3 skipped are platform-\nconditional sim tests).\n\ndevbar 1.10.5 is a workspace re-resolve bump.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): JSON-stdin batching + app/date/run hierarchy (1.20.0)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-27T03:42:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b83fbaa5fedf32798d0f105838d6e421704a9403",
          "body": "Two new capture modes inspired by automazeio/proof — broaden sweetlink's\n\"evidence-of-work\" coverage from browser-only to terminal and native\nmobile simulators.\n\n`sweetlink term <command>` records any shell command's stdout/stderr\ninto asciicast v2 (`.cast`) plus a self-contained HTML player. The\npl\n[…]\ntates (booted vs shut-down) confirmed green.\n\nTotal: 2334 unit + 73 e2e tests pass.\n\ndevbar 1.10.4 is a workspace re-resolve bump.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): terminal + simulator capture (1.19.0)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-27T02:52:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f7f77fc6d32b7e55053ff4aba4f95337d6c574a7",
          "body": "Quick wins:\n- Compact one-line `screenshot ✓ path · WxH · KB · method` output\n  (multi-line behind SWEETLINK_VERBOSE=1).\n- ActionEntry.duration now populated from real wall-clock time on\n  click/fill; SUMMARY action timeline gets a \"Took\" column.\n- Session IDs are ISO timestamps (`session-2026-04-26\n[…]\ne2e/wave-features.spec.ts` (62/62 e2e\n+ 2334/2334 unit pass).\n\ndevbar 1.10.3 is a workspace re-resolve bump for the new sweetlink.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): 20 round-2 UX polishes (1.18.0)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-26T15:36:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e19eb34f00c59cabd60290e8e3a688e0cb54c48e",
          "body": "TDD'd against an isolated harness (e2e/_harness.ts) with each bug\ncaptured as a failing test before being fixed. 52 new e2e tests gating\nthe behaviours.\n\nBug fixes (all gated by e2e/*-bugs.spec.ts):\n- Recording manifest now counts in-session console errors and network\n  failures (was hardcoded 0); l\n[…]\napshot; CLI suppresses stack traces unless SWEETLINK_DEBUG=1.\n\ndevbar 1.10.2 is a workspace re-resolve bump for the new sweetlink.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): TDD audit — 9 bug fixes + 17 UX polishes (1.17.0)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-26T13:26:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "21da5fd68bf2aef98c10268044428f0d9bfdf273",
          "body": "1.10.0 was published with npm publish, which doesn't rewrite the\n@ytspar/sweetlink workspace:^ dependency to a concrete version.\nInstalling 1.10.0 fails outside the monorepo.\n\n1.10.1 is the same code, republished via pnpm publish which rewrites\nworkspace protocols. Deprecating 1.10.0 on npm so consumers upgrade.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(devbar): republish as 1.10.1 via pnpm (resolve workspace:^) (#4)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-24T17:30:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b159afff2053b90606525dc57e12dd7489dc54c2",
          "body": "Adds a new plugin entry point @ytspar/devbar/plugins/consent-debug.\n\nGated on window.zaraz: polls until Cloudflare's consent API is injected,\nthen registers a \"Consent\" toolbar control. Clicking opens a modal for\nQA'ing cookie-consent flows without a VPN:\n\n- Mock geo regions (EU-DE/FR, UK, CA, VA, J\n[…]\naked in.\n\n1214/1214 tests pass; 4 new specs cover immediate registration,\ndeferred registration, timeout, and cleanup-during-wait.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(devbar): consent-debug plugin (1.10.0) (#3)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-24T17:28:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "51cc5867cbdd92deb91f6d88c90f04c40ade7855",
          "body": null,
          "is_bot": false,
          "headline": "chore(release-notes): sweetlink 1.16.1",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-23T10:09:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3ecea1338d70295c7d0feaa4705d8547e2456df9",
          "body": "Node's CJS resolver needs a 'require' or 'default' condition to resolve\nESM-only subpath exports when consumed from a non-ESM package. Without\nit, any consumer whose package.json lacks \\`\\\"type\\\": \\\"module\\\"\\` (the\ndefault) hits ERR_PACKAGE_PATH_NOT_EXPORTED on imports like\n@ytspar/sweetlink/browser\n[…]\ner\nor tsx in CJS mode without forcing them to declare type: module.\n\nReported by the security1000 repo, which was carrying a local pnpm\npatch for this. The patch can now be removed in favor of 1.16.1.",
          "is_bot": false,
          "headline": "fix(sweetlink): add default condition to subpath exports (1.16.1)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-23T09:55:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a8f266110ff8da47fc4986b7afd2473c47284595",
          "body": "3 eval cases per skill (2 positive triggers + 1 negative routing test):\n- screenshot, console-check-sweetlink, responsive-screenshots, resize-for-claude\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): add eval test cases for all bundled Claude skills",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-04T19:28:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c4adce7b796e06ae39eaca3abf3ea649e1365fc9",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump sweetlink to v1.16.0",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-04T17:34:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bd745d288f3b5f1bae7530724c504c3c5ecbbc2c",
          "body": "Move sweetlink-related Claude Code resources from enrichlayer/tools\ninto the sweetlink package so they ship with npm publish. Consumers\nget screenshot, console-check, responsive-screenshots, resize-for-claude\nskills, the sweetlink-visual-iterative agent, and architecture/CDP/\nverification context files out of the box.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): bundle Claude skills, agents, and context files",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-04-04T17:33:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "56e8aece004d01a04269cbeb3aa5d31bf6b94df4",
          "body": "The prepublishOnly hook runs check-release-notes.mjs which requires\na matching entry in release-notes.json. Canary versions like\n1.15.0-canary.84b58f0 don't have entries — only stable versions do.\n\nFix: strip the prerelease suffix (everything after the first hyphen)\nand check for the base version instead. 1.15.0-canary.84b58f0 now\nmatches the 1.15.0 release note entry.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: canary release — strip prerelease suffix in release notes check",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T20:16:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "84b58f0ce7f9597109ea3846b9834afa2d867c43",
          "body": "sweetlink v1.15.0: Demo docs, universal sharing, error detection,\nSUMMARY.md, git metadata, overlay toggle, HiFi from UI, comparison tables\n\ndevbar v1.9.2: Demo button + HiFi Alt+Click in toolbar, recording\nauto-opens viewer, demo state fields\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump sweetlink to v1.15.0, devbar to v1.9.2",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T20:10:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "66f10b50321ae2c10c33a706156dafd891aeb364",
          "body": "TST1: Add demo.test.ts (34 new tests) covering initDemo, addNote,\n  addExec, addScreenshot, addSnapshot, popSection, renderDemo,\n  verifyDemo, writeDemo — with mocked fs and child_process\n\nBUN1/errorPatterns: Wire detectServerErrors() into record-stop flow.\n  The errorPatterns module was created but\n[…]\ner defaults. Not stale.\n\nBUN1: 5 \"dead\" files are config files and CLI entry points. Not dead.\n\n87 test files, 2330 tests passing.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: address all product-finalizer audit findings",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T19:38:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "34da7ef346d9e42a9dd8a1a780e69d404e7b1f4d",
          "body": "Replaces the old 11-row comparison table with three detailed tables\ncovering all v2 features:\n\n1. Screenshot & Interaction: vs Playwright CLI, Chrome DevTools MCP,\n   agent-browser — covers token cost, fast/hifi/responsive screenshots,\n   device emulation, @ref system, persistent sessions\n\n2. Eviden\n[…]\nrt, a11y, vitals, ruler\n\nAlso updates \"When to Use\" section to reflect v2 capabilities\n(always-on capture, demo docs, toolbar UI).\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: add comprehensive comparison tables vs alternatives",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T17:55:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "babc4edc25cf2ef36d1339853f459bb7616432be",
          "body": "UI additions:\n- Screenshot button: Alt+Click takes pixel-perfect HiFi screenshot\n  via daemon (tooltip updated with new shortcut)\n- Demo button: pencil icon between Record and Settings\n  - Click to start demo (prompts for title)\n  - While active: click adds screenshot, shows section count\n\nWS server\n[…]\nreenshotCommand added to SweetlinkCommand union\n- Demo state fields added to DevBarState (demoActive, demoTitle, demoSectionCount)\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(devbar): HiFi screenshot via Alt+Click, demo button in toolbar",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T17:19:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e0e60579270f1cdd649664a16b6abecfa5b579eb",
          "body": "Builds Markdown demo documents step-by-step as agents work.\nEach command appends a section with embedded outputs and screenshots.\nThe result is a reproducible tutorial/proof document.\n\nNew module (daemon/demo.ts):\n- initDemo(title): Start new document with git metadata\n- addNote(text): Append prose \n[…]\nFirst, run the tests:\n  ```bash\n  $ pnpm test -- --grep search\n  ✓ 3 tests passed\n  ```\n  ![Search results](demo-screenshot-1.png)\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): demo document builder (Showboat-inspired)",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T16:54:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6cc08bd7a87e9fd55f8f510f8fb3f5f1b645062f",
          "body": "… new)\n\nAddresses TST1 audit finding — 3 critical daemon modules now have tests.\n\nerrorPatterns.test.ts (49 tests):\n  All 10 language categories (JS, Python, Go, Java, Rust, Ruby, PHP,\n  C#, Elixir, generic), clean output, multi-line, result shape\n\nsummary.test.ts (25 tests):\n  Markdown structure, g\n[…]\nntical/different buffers, threshold controls, different lengths,\n  empty buffers, result shape\n\n86 test files, 2296 tests passing.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(sweetlink): add tests for errorPatterns, summary, visualDiff (92…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T05:39:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7bdfd3d4d113a00cce0722e36f95c710e1e01f75",
          "body": "Fixes two issues from hook feedback:\n\n1. report --serve: Now binds to 0.0.0.0 (all interfaces) instead of\n   loopback. Prints both local and network URLs with LAN IP auto-detection.\n   Other devices on the network can now access the served viewer.\n\n2. Viewer Copy Report: Falls back to document.execC\n[…]\n.clipboard is unavailable (file:// contexts, non-HTTPS).\n   The downloaded standalone viewer now works offline for clipboard copy.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(sweetlink): bind --serve to 0.0.0.0 + clipboard fallback for file://",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T05:34:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8e6d86f8b1e1c89ce991c5f15a00f8199917fd3c",
          "body": "…e buttons\n\nPlatform-agnostic session sharing that works with any tool:\n\nCLI `report` command:\n- `sweetlink report` — prints SUMMARY.md to stdout (pipe anywhere)\n- `sweetlink report --clipboard` — copies to clipboard (pbcopy/xclip)\n- `sweetlink report --serve` — serves viewer.html on temporary local\n[…]\nThe summary markdown is generated at viewer build time and embedded\nin the HTML as a JS variable, so clipboard copy works offline.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): universal sharing — CLI report command + viewer shar…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T05:31:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "52445db1736033949e135d014d99568509c5b988",
          "body": "Fixes leaked blank tab and stale state when record-stop fails:\n\n- Handle both `record-stop-response` and `record-stop` message types\n  (server sends errors with the original type, not the -response suffix)\n- cleanupPendingWindow() helper closes blank tab + nulls state\n- On failure: close blank tab, \n[…]\n blank tab + resets state\n- record-stop error type: closes blank tab + resets state\n- record-stop with no pending window: no crash\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(devbar): clean up blank tab on record-stop failure + test coverage",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T05:10:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d917d4f156b1b478ad61608c470fe7599dd84724",
          "body": "Fixes three issues from hook feedback:\n\n1. Popup blocker: window.open() was called from async WS handler,\n   outside the original click gesture. Now opens window synchronously\n   on stop-click (about:blank), then navigates to viewerUrl when the\n   WS response arrives. Falls back to closing the blank\n[…]\nusers need offline access.\n\n3. New state field: pendingViewerWindow tracks the pre-opened window\n   between click and WS response.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(devbar): prevent popup blocker on viewer open, fix stale URL",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T05:06:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "838df7a478cfcf70585d77aa3bdb006f2f7cb043",
          "body": "The daemon now serves viewer.html via HTTP GET, so the browser can\nopen it directly. When recording stops from the devbar UI, the viewer\nauto-opens in a new tab.\n\nDaemon server:\n- GET /viewer/{sessionId}: Serves viewer.html (no auth, localhost only)\n- GET /viewers: Lists available sessions as JSON\n-\n[…]\nClick re-open\n\nFlow: Devbar button → WS → sweetlink server → daemon HTTP →\n  record-stop → viewerUrl → WS response → window.open()\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): serve viewer via daemon HTTP + auto-open from devbar",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T05:03:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6be678af9e6bcf09635077a77e03fa5774b1b56a",
          "body": "… overlays\n\nAbsorbs key features from ProofShot and Proof repos into Sweetlink v2.\n\nNew modules:\n- daemon/errorPatterns.ts: Multi-language server error detection (10+ languages)\n  JS/Node, Python, Ruby, Go, Java, Rust, PHP, C#, Elixir, generic patterns\n- daemon/summary.ts: SUMMARY.md report generato\n[…]\ne with emoji indicators\n\nSession manifest:\n- New fields: gitBranch, gitCommit\n- Auto-detected via git rev-parse at recording start\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): ProofShot/Proof features — error detection, summary,…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T04:44:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4fbda9ed55b4ada6df817fac7cadcc4612d91548",
          "body": "The viewer now shows a \"Back to app\" link in the header that navigates\nback to the recorded app URL. The link uses the target URL stored in\nthe session manifest.\n\nChanges:\n- session.ts: Add optional `url` field to SessionManifest\n- recording.ts: Store target URL during recording, include in manifest\n- viewer.ts: Render back link in header when URL is available\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): add back-to-app link in viewer header",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T04:29:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "873f645dc55803f4e780635e2b4cd4d2ad078df1",
          "body": "…ayer\n\nReplaces hardcoded colors with devbar design tokens across all\ngenerated HTML outputs:\n\nviewer.ts (session viewer):\n- CSS custom properties from devbar theme (--color-primary: #10b981, etc.)\n- Font: Departure Mono stack (with system monospace fallback)\n- Background: #0a0f1a (devbar dark bg), \n[…]\nemerald command text, card background\n- ANSI colors: emerald green, devbar red/amber\n- Typography: Departure Mono stack, 0.6875rem\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "style: apply devbar design system to viewer, annotations, terminal pl…",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T04:26:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "81425d2bb7bc4ff9a9fa0b761d25802141323b7a",
          "body": "Addressed all findings from thorough documentation audit:\n\nsweetlink/README.md:\n- Add 14 missing CLI commands/flags: wait, status, cleanup, --app,\n  --force-ws, --no-wait, --wait-timeout, --width, --height, --hifi,\n  --responsive, network --failed/--last\n- Add Schema/Outline/A11y/Vitals command sect\n[…]\nf command to CLI reference\n- Add --headed flag to daemon start\n- Add wait, status, vitals, a11y, schema, outline, cleanup commands\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: comprehensive documentation update from full audit",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T04:04:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7a274458c4063a0e6bf6c9988d854a5553e103b9",
          "body": "Multi-instance:\n- Daemon state files scoped by app port: daemon-3000.json, daemon-5173.json\n- Lock files also scoped: daemon-3000.lock, daemon-5173.lock\n- Two apps in same monorepo can run separate daemons simultaneously\n- CLI --url determines which daemon to start/connect to\n\nVite plugin auto-start\n[…]\n, concurrently, manual lifecycle\n- Multi-app monorepo setup: separate daemons per port\n- CLI quick reference for daemon management\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sweetlink): multi-instance daemon support + Vite auto-start",
          "author_name": "Yury Tsukerman",
          "author_login": "ytspar",
          "committed_at": "2026-03-26T04:00:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 33,
      "commits_last_year": 266,
      "latest_release_at": "2026-07-21T14:38:05Z",
      "latest_release_tag": "sweetlink-v1.27.0",
      "releases_from_tags": false,
      "days_since_last_push": 8,
      "active_weeks_last_year": 19,
      "days_since_latest_release": 8,
      "mean_days_between_releases": 4.8
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@ytspar/devbar",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "development",
            "debug",
            "devbar",
            "sweetlink",
            "vanilla-js"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@ytspar/devbar",
          "is_deprecated": false,
          "latest_version": "1.18.3",
          "repository_url": "https://github.com/ytspar/devbar",
          "versions_count": 150,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 5712,
          "first_published_at": "2026-01-29T05:12:41.371000Z",
          "latest_published_at": "2026-07-17T19:10:43.683000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 12
        },
        {
          "name": "@ytspar/sweetlink",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "autonomous-development",
            "ai-agents",
            "screenshot",
            "websocket",
            "chrome-devtools-protocol",
            "development-tools",
            "debugging",
            "vanilla-js"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@ytspar/sweetlink",
          "is_deprecated": false,
          "latest_version": "1.27.1",
          "repository_url": "https://github.com/ytspar/devbar",
          "versions_count": 141,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 11733,
          "first_published_at": "2026-01-29T05:12:31.174000Z",
          "latest_published_at": "2026-07-28T12:55:34.332000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 1
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 1,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 2
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": true,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "packages/devbar/tsconfig.json",
        "packages/playground/tsconfig.json",
        "packages/sweetlink/tsconfig.json",
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 163647,
      "source_files_sampled": 271,
      "oversized_source_files": 3,
      "agent_instruction_files": [
        "AGENTS.md",
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 7449
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 9,
        "malicious_count": 0,
        "assessed_package": "npm:@ytspar/devbar@1.18.3",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@ytspar/sweetlink",
          "manifest": "packages/devbar/package.json",
          "ecosystem": "npm",
          "version_constraint": "workspace:^"
        },
        {
          "name": "axe-core",
          "manifest": "packages/devbar/package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.10.2"
        },
        {
          "name": "html2canvas-pro",
          "manifest": "packages/devbar/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.0"
        },
        {
          "name": "@ytspar/devbar",
          "manifest": "packages/playground/package.json",
          "ecosystem": "npm",
          "version_constraint": "workspace:*"
        },
        {
          "name": "@ytspar/sweetlink",
          "manifest": "packages/playground/package.json",
          "ecosystem": "npm",
          "version_constraint": "workspace:*"
        },
        {
          "name": "dotenv",
          "manifest": "packages/sweetlink/package.json",
          "ecosystem": "npm",
          "version_constraint": "^17.2.4"
        },
        {
          "name": "ws",
          "manifest": "packages/sweetlink/package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.18.3"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 34,
        "open_issues": 2,
        "closed_ratio": 0,
        "closed_issues": 0,
        "closed_unmerged_prs": 1
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "ytspar",
          "commits": 260,
          "avatar_url": "https://avatars.githubusercontent.com/u/365593?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "playground.yml",
        "release-notes-gate.yml",
        "release-please.yml",
        "release.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [
        "biome.json"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "pnpm-lock.yaml"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 2,
            "reason": "5 out of 23 merged PRs checked by a CI test -- score normalized to 2",
            "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/24 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 6,
            "reason": "project has 2 contributing companies or organizations -- score normalized to 6",
            "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 0 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": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "15 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "48cfa865e8c224fccf426d5bc3510d64a1487c25",
        "ran_at": "2026-07-30T01:21:27Z",
        "aggregate_score": 3.2,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-21T14:39:21Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-21T14:37:56Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 1,
          "created_at": "2026-01-29T16:53:11Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 2,
          "created_at": "2026-02-11T16:29:23Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/ytspar/devbar",
    "host": "github.com",
    "name": "devbar",
    "owner": "ytspar"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 55,
      "inputs": {
        "security": 46,
        "vitality": 82,
        "community": 36,
        "governance": 48,
        "engineering": 57
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 82,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "commits_last_year": 266,
              "human_commit_share": 0.94,
              "days_since_last_push": 8,
              "active_weeks_last_year": 19
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 8 days ago",
                "points": 28.8,
                "status": "partial",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "19/52 weeks with commits",
                "points": 13.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 19
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "266 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 266
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "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": 33,
              "latest_release_tag": "sweetlink-v1.27.0",
              "releases_from_tags": false,
              "days_since_latest_release": 8,
              "mean_days_between_releases": 4.8
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "33 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 33
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 8 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~4.8 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 4.8
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 8,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 8 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 36,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 1,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "1 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "good",
            "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": 71,
            "inputs": {
              "packages": [
                "@ytspar/devbar",
                "@ytspar/sweetlink"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 17445
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "17,445 downloads/month across npm",
                "points": 56.6,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 17445,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 48,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 16,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 2 contributing companies or organizations -- score normalized to 6",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "at_risk",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 37,
            "inputs": {
              "merged_prs": 34,
              "open_issues": 2,
              "closed_issues": 0,
              "issue_closed_ratio": 0,
              "closed_unmerged_prs": 1
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "0% of issues closed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 0
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "34/35 decided PRs merged",
                "points": 37.2,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 34,
                      "decided": 35
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/24 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 54,
            "inputs": {
              "followers": 36,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "ytspar",
              "public_repos": 20,
              "account_age_days": 5826
            },
            "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": "36 followers of ytspar",
                "points": 11.3,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 36,
                      "login": "ytspar"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "20 public repos, account ~15 yr old",
                "points": 21.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 20
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 15
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "@ytspar/devbar",
                "@ytspar/sweetlink"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 1
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "2 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 2,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 1 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 1
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "150 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 150
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 57,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "4 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": "biome.json",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "biome.json"
                    }
                  }
                ],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "5 out of 23 merged PRs checked by a CI test -- score normalized to 2",
                "points": 4,
                "status": "partial",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "at_risk",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": false,
              "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 46,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "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": 32,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 3.2
            },
            "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 23 merged PRs checked by a CI test -- score normalized to 2",
                "points": 0.5,
                "status": "partial",
                "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/24 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 2 contributing companies or organizations -- score normalized to 6",
                "points": 1.5,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 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": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "15 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the npm:@ytspar/devbar@1.18.3 runtime dependency closure — what installing the published package pulls in — 9 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:@ytspar/devbar@1.18.3",
                  "assessed": 9
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 9,
              "unassessed_packages": 0,
              "affected_by_severity": "none",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "no indirect dependency carries a known advisory",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "no_indirect_advisories",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 9,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 1
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 83,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "has_llms_txt": true,
              "legible_history_share": 0.83,
              "agent_instruction_files": [
                "AGENTS.md",
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 7449
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md, CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.md, CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": "llms.txt present",
                "points": 15,
                "status": "met",
                "details": [
                  {
                    "code": "llms_txt_present",
                    "params": {}
                  }
                ],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "78 of 94 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 78,
                      "sampled": 94
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 64,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "pnpm-lock.yaml"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "packages/devbar/tsconfig.json",
                "packages/playground/tsconfig.json",
                "packages/sweetlink/tsconfig.json",
                "tsconfig.json"
              ],
              "agent_commit_share": 0.54,
              "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": "biome.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "biome.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "packages/devbar/tsconfig.json, packages/playground/tsconfig.json, packages/sweetlink/tsconfig.json, tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "packages/devbar/tsconfig.json, packages/playground/tsconfig.json, packages/sweetlink/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": "54 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 54,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 99,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 163647,
              "source_files_sampled": 271,
              "oversized_source_files": 3
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "3/271 source files over 60KB",
                "points": 54.4,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 271,
                      "oversized": 3
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-30T01:21:40.151954Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/y/ytspar/devbar.svg",
  "full_name": "ytspar/devbar",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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