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

clagentic / clagentic-console

A self-hosted browser console for Claude Code and ChatGPT Codex. Run AI sessions from any browser or phone — tool approvals, model selection, context management, session history — without leaving your own machine.

JavaScript · CSSMIT★ 3 estrellas⑂ 0 forksdesde may 2026Ver en GitHub ↗

clagentic/clagentic-console tiene un índice de salud de 57 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Vitality (83/100) y la más baja, Security (22/100). Se actualizó por última vez hoy. Una sola persona concentra la mayor parte del trabajo reciente.

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

57
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

ClagenticOrganización
0 seguidores7 repositorios públicosdesde abr 2026

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

Ecosistemas de paquetes

Métricas por categoría

Vitalidad

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

83Bueno · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 0 días
16.6/36Cadencia de commits — 24/52 semanas con commits
18/18Volumen de commits — 2650 commits en el último año
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Datos de entrada utilizados
commits_last_year2650
human_commit_share0,02
days_since_last_push0
active_weeks_last_year24
Cómo se puntúa
27/27Publica versiones — 45 versiones publicadas
36/36Recencia de las versiones — última versión hace 5 días
27/27Cadencia de publicación — una versión cada ~2,5 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count45
latest_release_tagv1.8.0-beta.1
releases_from_tagsno
days_since_latest_release5
mean_days_between_releases2,5
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?

40En riesgo · 18% del índice global
Cómo se puntúa
4.9/60Estrellas — 3 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars3
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)
18/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_contributing
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno
Cómo se puntúa
44.7/80Descargas mensuales — 2243 descargas/mes en npm
0/20Dependientes en el registro — no lo informa este ecosistema
Datos de entrada utilizados
packages@clagentic/console
dependents
ecosystemsnpm
total_downloads
monthly_downloads2243
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?

54Moderado · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
10.6/22.5Distribución de commits — el principal contribuyente firma el 53% de los commits
13.5/13.5Amplitud de contribuyentes — 16 contribuyentes
10/10OpenSSF Scorecard: Contributors — project has 5 contributing companies or organizations
Datos de entrada utilizados
bus_factor1
contributors_sampled16
top_contributor_share0,529
Cómo se puntúa
7.8/46.8Resolución de issues — 17% de issues cerradas
37.9/38.3Aceptación de PR — 361/364 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/1 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs361
open_issues5
closed_issues1
issue_closed_ratio0,167
closed_unmerged_prs3
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
0/25Alcance del propietario — 0 seguidores de clagentic
7.1/25Trayectoria — 7 repos públicos, cuenta de ~0 años
Datos de entrada utilizados
followers0
owner_typeOrganization
is_verified
owner_loginclagentic
public_repos7
account_age_days89
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en npm
35/35Recencia de publicación — última publicación hace 8 días
20/20Historial de versiones — 46 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packages@clagentic/console
ecosystemsnpm
any_deprecatedno
min_days_since_publish8

Calidad de Ingeniería

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

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

Documentación

90Excelente
Cómo se puntúa
30/30README
25/25Directorio de documentación
15/15Sitio de documentación / página del proyecto — https://clagentic.ai
10/10Descripción del repositorio
10/10Topics — 7 topics
0/10Wiki
Datos de entrada utilizados
topicsai-tooling, browser-ui, claude-code, developer-tools, pwa, self-hosted, clagentic-tool
has_wikino
homepagehttps://clagentic.ai
has_readme
has_docs_dir
has_description

Seguridad

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

22Crítico · 16% del índice global
Cómo se puntúa
7.5/7.5Binary-Artifacts — no binaries found in the repo
0.8/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 8 out of 8 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/1 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 5 contributing companies or organizations
0/10Dangerous-Workflow — 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
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
5/5Packaging — packaging workflow detected
1/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 2
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 — 51 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate2,2
Excluidos de la puntuación (sin datos o no aplicable): signed_releases. Los pesos restantes se han renormalizado.

Preparación para IA

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

32En riesgo · 0% del índice global
Cómo se puntúa
0/45Instrucciones para agentes — sin CLAUDE.md / AGENTS.md / reglas de editor
15/15Documentación legible por máquinas (llms.txt) — llms.txt presente
0/40Historial de commits legible — sin datos
Datos de entrada utilizados
has_llms_txt
legible_history_share
agent_instruction_files
agent_instruction_max_bytes
Excluidos de la puntuación (sin datos o no aplicable): Historial de commits legible. Los pesos restantes se han renormalizado.
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
0/11Configuración de lint / formato
0/11Verificación estática de tipos
10/10Entorno reproducible — lockfile
0/10Práctica demostrada con agentes — ningún commit con autoría de agente entre los últimos 100
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
2/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 2
Datos de entrada utilizados
has_nixno
has_tests
lockfilespackage-lock.json
has_dockerfileno
typed_languageno
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0
toolchain_manifests
dependency_bot_commit_share0
Cómo se puntúa
0/45Código verificable por tipos — JavaScript sin configuración de verificación de tipos
52.3/55Tamaños de archivo manejables — 14/288 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageJavaScript
largest_source_bytes103.115
source_files_sampled288
oversized_source_files14
Cómo se puntúa
0/40Esquema de API (OpenAPI/GraphQL/proto)
20/20Servidor MCP
0/40Ejemplos ejecutables
Datos de entrada utilizados
example_dirs
has_mcp_signal
api_schema_files

Datos clave

3estrellas de GitHub
16contribuidores
2650commits en los últimos 12 meses
0días desde el último push
45versiones publicadas
1factor bus
5issues abiertas
npmecosistemas de paquetes

Advertencias de recopilación de datos

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index npm:@clagentic/console@1.7.0; advisories assessed against the repository dependency graph instead

Más detalle

OpenSSF Scorecard 2.2 / 10
2.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-23 03:52 UTC

10Binary-Artifactsno binaries found in the repo
1Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests8 out of 8 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/1 approved changesets -- score normalized to 0
10Contributorsproject has 5 contributing companies or organizations
0Dangerous-Workflowdangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
10Packagingpackaging workflow detected
2Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 2
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
0Vulnerabilities51 existing vulnerabilities detected
Dependencias directas 8
RegistroPaqueteRestricción de versiónManifiesto
npm@anthropic-ai/claude-agent-sdk^0.3.173package.json
npm@anthropic-ai/sdk^0.104.1package.json
npm@lydell/node-pty^1.2.0-beta.3package.json
npm@openai/codex^0.124.0package.json
npmnodemailer^6.10.1package.json
npmqrcode-terminal^0.12.0package.json
npmweb-push^3.6.7package.json
npmws^8.18.0package.json
Todas las dependencias no recopilado

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

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [
        "ai-tooling",
        "browser-ui",
        "claude-code",
        "developer-tools",
        "pwa",
        "self-hosted",
        "clagentic-tool"
      ],
      "is_fork": false,
      "size_kb": 39106,
      "has_wiki": false,
      "homepage": "https://clagentic.ai",
      "languages": {
        "CSS": 595408,
        "HTML": 121674,
        "Shell": 1273,
        "JavaScript": 4312907
      },
      "pushed_at": "2026-07-22T21:14:03Z",
      "created_at": "2026-05-06T18:47:24Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-22T21:14:12Z",
      "description": "A self-hosted browser console for Claude Code and ChatGPT Codex. Run AI sessions from any browser or phone — tool approvals, model selection, context management, session history — without leaving your own machine. ",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "JavaScript",
      "significant_languages": [
        "JavaScript",
        "CSS"
      ]
    },
    "owner": {
      "blog": "https://clagentic.ai",
      "name": "Clagentic",
      "type": "Organization",
      "login": "clagentic",
      "company": null,
      "location": "United States of America",
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/279098901?v=4",
      "created_at": "2026-04-24T19:15:59Z",
      "is_verified": null,
      "public_repos": 7,
      "account_age_days": 89
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v1.8.0-beta.1",
          "kind": "prerelease",
          "published_at": "2026-07-17T20:17:47Z"
        },
        {
          "tag": "v1.7.1-beta.1",
          "kind": "prerelease",
          "published_at": "2026-07-16T12:31:26Z"
        },
        {
          "tag": "v1.7.0",
          "kind": "minor",
          "published_at": "2026-07-14T20:53:18Z"
        },
        {
          "tag": "v1.7.0-beta.1",
          "kind": "prerelease",
          "published_at": "2026-07-14T13:05:30Z"
        },
        {
          "tag": "v1.6.0",
          "kind": "minor",
          "published_at": "2026-07-07T12:47:39Z"
        },
        {
          "tag": "v1.6.0-beta.4",
          "kind": "prerelease",
          "published_at": "2026-07-06T11:36:54Z"
        },
        {
          "tag": "v1.6.0-beta.3",
          "kind": "prerelease",
          "published_at": "2026-07-05T21:26:05Z"
        },
        {
          "tag": "v1.6.0-beta.2",
          "kind": "prerelease",
          "published_at": "2026-07-01T23:12:35Z"
        },
        {
          "tag": "v1.6.0-beta.1",
          "kind": "prerelease",
          "published_at": "2026-06-30T16:50:10Z"
        },
        {
          "tag": "v1.5.0",
          "kind": "minor",
          "published_at": "2026-06-25T18:26:39Z"
        },
        {
          "tag": "v1.5.0-beta.4",
          "kind": "prerelease",
          "published_at": "2026-06-25T16:11:05Z"
        },
        {
          "tag": "v1.5.0-beta.3",
          "kind": "prerelease",
          "published_at": "2026-06-17T17:29:36Z"
        },
        {
          "tag": "v1.5.0-beta.2",
          "kind": "prerelease",
          "published_at": "2026-06-12T10:43:37Z"
        },
        {
          "tag": "v1.5.0-beta.1",
          "kind": "prerelease",
          "published_at": "2026-06-11T20:31:47Z"
        },
        {
          "tag": "v1.4.1",
          "kind": "patch",
          "published_at": "2026-06-08T18:13:55Z"
        },
        {
          "tag": "v1.4.0",
          "kind": "minor",
          "published_at": "2026-06-06T13:48:22Z"
        },
        {
          "tag": "v1.4.0-beta.3",
          "kind": "prerelease",
          "published_at": "2026-06-05T19:19:09Z"
        },
        {
          "tag": "v1.4.0-beta.2",
          "kind": "prerelease",
          "published_at": "2026-05-31T14:41:08Z"
        },
        {
          "tag": "v1.4.0-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-31T11:58:37Z"
        },
        {
          "tag": "v1.3.1-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-29T19:20:58Z"
        },
        {
          "tag": "v1.3.0",
          "kind": "minor",
          "published_at": "2026-05-29T18:25:36Z"
        },
        {
          "tag": "v1.3.0-beta.2",
          "kind": "prerelease",
          "published_at": "2026-05-29T15:57:54Z"
        },
        {
          "tag": "v1.3.0-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-29T14:43:38Z"
        },
        {
          "tag": "v1.2.1-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-26T13:20:27Z"
        },
        {
          "tag": "v1.2.0",
          "kind": "minor",
          "published_at": "2026-05-22T12:26:27Z"
        },
        {
          "tag": "v1.2.0-beta.2",
          "kind": "prerelease",
          "published_at": "2026-05-19T20:10:06Z"
        },
        {
          "tag": "v1.2.0-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-19T17:54:55Z"
        },
        {
          "tag": "v1.1.1-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-19T15:24:39Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2026-05-18T22:29:52Z"
        },
        {
          "tag": "v1.1.0-beta.2",
          "kind": "prerelease",
          "published_at": "2026-05-18T20:37:32Z"
        },
        {
          "tag": "v1.1.0-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-18T17:10:24Z"
        },
        {
          "tag": "v1.0.5-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-18T12:35:18Z"
        },
        {
          "tag": "v1.0.4",
          "kind": "patch",
          "published_at": "2026-05-15T21:29:02Z"
        },
        {
          "tag": "v1.0.4-beta.3",
          "kind": "prerelease",
          "published_at": "2026-05-15T21:23:31Z"
        },
        {
          "tag": "v1.0.4-beta.2",
          "kind": "prerelease",
          "published_at": "2026-05-15T21:22:01Z"
        },
        {
          "tag": "v1.0.4-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-15T12:08:05Z"
        },
        {
          "tag": "v1.0.3",
          "kind": "patch",
          "published_at": "2026-05-14T13:47:42Z"
        },
        {
          "tag": "v1.0.3-beta.2",
          "kind": "prerelease",
          "published_at": "2026-05-14T13:09:13Z"
        },
        {
          "tag": "v1.0.3-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-14T02:40:12Z"
        },
        {
          "tag": "v1.0.2",
          "kind": "patch",
          "published_at": "2026-05-14T02:33:34Z"
        },
        {
          "tag": "v1.0.1",
          "kind": "patch",
          "published_at": "2026-05-13T23:15:21Z"
        },
        {
          "tag": "v1.0.1-beta.1",
          "kind": "prerelease",
          "published_at": "2026-05-13T23:08:37Z"
        },
        {
          "tag": "v1.0.0-beta.4",
          "kind": "prerelease",
          "published_at": "2026-05-13T15:01:51Z"
        },
        {
          "tag": "v1.0.0-beta.3",
          "kind": "prerelease",
          "published_at": "2026-05-13T14:54:47Z"
        },
        {
          "tag": "v1.0.0-beta.2",
          "kind": "prerelease",
          "published_at": "2026-05-13T12:52:54Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "1cddcc115ad0b2a115d91b80e2b4abe805738052",
          "body": "fix(css): give warn/error toast overlays an opaque background (lr-136f81)",
          "is_bot": true,
          "headline": "Merge pull request #370 from clagentic/fix/lr-136f81-toast-opaque-bg",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-22T21:14:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "78518dc2ea9a0f078c6aab8ed6bc5be2030d06dd",
          "body": "…f81)\n\n.toast-warn used --warning-bg (12% alpha), a token designed for inline\ndiagnostic badges inside an already-opaque panel. On a position:fixed\noverlay toast, that translucency let chat content behind it bleed\nthrough and the toast read as malformed. Layer the tint over the\nopaque --bg-alt toast\n[…]\ncted). Also add a matching .toast-error rule --\nerror-level toasts (utils.js showToast level=\"error\") had no\ndedicated CSS and would otherwise gain the same translucency bug if\none were added naively.",
          "is_bot": true,
          "headline": "fix(css): give warn/error toast overlays an opaque background (lr-136…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-22T21:06:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1a6540d4288768b5b4c78d845c35a2b41a27fbe7",
          "body": "…ons-icon-abbrev\n\nfix(home-hub): render getProjectAbbrev fallback for blank recent-session icons (lr-e5faff)",
          "is_bot": true,
          "headline": "Merge pull request #369 from clagentic/fix/lr-e5faff-hub-recent-sessi…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-21T23:35:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6075a6bf46e39e4c20083852280db9bf81146dfe",
          "body": "…ion icons (lr-e5faff)\n\nhandleHubRecentSessions() emitted an empty .hub-recent-project-icon--blank\nspan when sess.projectIcon was falsy (default text-based project identity,\nno emoji/custom :slug: icon), so those projects appeared to have no icon\nin the Home Hub RECENT SESSIONS card. Emoji/custom-ic\n[…]\nsting full-suite\nflakes unrelated to this change, 1 documented skip — verified by diffing\nfail counts before/after this diff, which dropped from 6 to 4 exactly\nmatching the 2 tests this fix resolves).",
          "is_bot": true,
          "headline": "fix(home-hub): render getProjectAbbrev fallback for blank recent-sess…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-21T23:29:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "770363db0a36a963a59d5c8d5bce114019c63678",
          "body": "…dangling-refs\n\nfix(cli): remove dangling toClayStudioUrl call sites (lr-db24ec)",
          "is_bot": true,
          "headline": "Merge pull request #368 from clagentic/fix/lr-db24ec-toclaystudiourl-…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-19T17:04:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2410c8db693b7323d4cbca293655606c804e008a",
          "body": "Regression coverage for lr-db24ec: a static guard against toClayStudioUrl\nand config.builtinCert being reintroduced into bin/cli.js or\nlib/cli/menus.js, plus a smoke test proving both the studio-status URL\npath and the recovery-URL path render a URL without throwing, for both\nhttp and https.",
          "is_bot": true,
          "headline": "test(cli): smoke-test the two dangling-URL call sites (lr-db24ec)",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-19T16:58:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0d83486038ea0f40f020e10e590f71d9309823c7",
          "body": "toClayStudioUrl(ip, port, protocol) and the config.builtinCert flag that\ngated it were both removed in lr-8406 (\"remove pre-fork builtin cert\"),\nbut two call sites survived: bin/cli.js's headless daemon-already-running\nstatus path, and the recover_admin recovery-URL path later relocated\nverbatim int\n[…]\nse on the account-recovery path.\n\nBoth dead ternary branches are dropped; both paths now build the URL the\nsame way every other call site in this file already does:\nprotocol + \"://\" + ip + \":\" + port.",
          "is_bot": true,
          "headline": "fix(cli): remove dangling toClayStudioUrl call sites (lr-db24ec)",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-19T16:57:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7a26c2585fdeb79e69de32dfc27eb12404387a62",
          "body": "…erlap\n\nfix(home-hub): clear search bar from close button overlap on mobile (lr-ea6c65)",
          "is_bot": true,
          "headline": "Merge pull request #367 from clagentic/fix/lr-ea6c65-hub-close-btn-ov…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-19T14:13:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9a5b6ccdb3a56710e3b2c564dcff0734add2ac88",
          "body": "…lr-ea6c65)",
          "is_bot": true,
          "headline": "fix(home-hub): clear search bar from close button overlap on mobile (…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-19T14:05:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d834f750be7733c61c8d4ab71adff9fc3bb11965",
          "body": "…ons-merge-dot\n\nfix(home-hub): merge alert dot into single left status dot (lr-0aa7b6)",
          "is_bot": true,
          "headline": "Merge pull request #366 from clagentic/fix/lr-0aa7b6-hub-recent-sessi…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-18T17:43:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "197febab63b883f08171706b6b5bc1e330675106",
          "body": "… (lr-0aa7b6)\n\nExtends the existing merge-dot test to assert the alert state is keyed\non sess.unread, not projectHasAlert(sess.projectSlug), and removes the\nnow-stale KNOWN LIMITATION assertion.\n\nAdds server-cross-project-unread-per-session-lr-0aa7b6.test.js:\n- onSessionDone(session.localId) is call\n[…]\n\n  project-badge rollup sums correctly.\n- hub_recent_sessions_list (real attachLoop) only marks the notifying\n  session's sess.unread, and resolves same-localId cross-project\n  sessions independently.",
          "is_bot": true,
          "headline": "test(home-hub): cover per-session unread data path and dot precedence…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T17:36:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8dc08580dadcd21e50ebbe70dc5c9a2894612589",
          "body": "…r-0aa7b6)\n\nhandleHubRecentSessions now derives hasAlert from sess.unread — the\nsession's own per-session unread count carried from the server data\npath (previous commit) — instead of projectHasAlert(sess.projectSlug),\nwhich lit every sibling session's row in a notifying project even when\nonly one session was actually notifying. projectHasAlert itself is\nkept: it still backs the separate Projects-list unread badge.",
          "is_bot": true,
          "headline": "fix(home-hub): key recent-sessions alert dot on per-session unread (l…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T17:35:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "49561567ded96c5535a7637010d520899d7ab58f",
          "body": "… (lr-0aa7b6)\n\nlib/server.js's crossProjectUnread map was keyed by project slug alone,\nso a session finishing in one project marked the WHOLE project as\nhaving unread activity. Restructured to key by composite\n\"slug::localId\" (crossUnreadKey), threaded session identity through\nlib/sessions.js's onSe\n[…]\ntries).\n\nlib/project.js and lib/project-loop.js thread getSessionUnread through\nto hub_recent_sessions_list, which now attaches each session's own\nunread count onto the sess object sent to the client.",
          "is_bot": true,
          "headline": "fix(home-hub): restructure cross-project unread to per-session keying…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T17:35:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9a45d82b07cd4c6bb763e96d907ac4ed9a6f6564",
          "body": "…n (lr-0aa7b6)\n\nReplaces test/hub-recent-sessions-alert-dot-lr-2b1f03.test.js (asserted\nthe old two-dot design this task removes) with coverage of the merged\nsingle dot: no leftover .hub-recent-alert-dot markup/CSS rule, alert\nbranch ordered ahead of processing in the color-precedence ternary,\ntooltip preserved per state, and the per-project (not yet per-session)\nlimitation documented with a TODO(lr-0aa7b6).",
          "is_bot": true,
          "headline": "test(home-hub): assert merged-dot precedence and removal of alert spa…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T16:32:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8c59d449c205f28e135d969058f464e5c8be69ea",
          "body": "Recent Sessions rows showed TWO indicators: a left status dot\n(.hub-recent-dot) and a separate right red alert dot\n(.hub-recent-alert-dot, lr-2b1f03). Merge into ONE left dot whose\ncolor encodes everything, with LOCKED precedence (andy, confirmed):\nalert(red) > processing(green) > live(green) > idle\n[…]\nt-badge unread count depends on today - larger\nthan a data-path extension, so per task instruction this is flagged\nrather than shipped as a silent per-project fallback dressed up as\na per-session fix.",
          "is_bot": true,
          "headline": "fix(home-hub): merge alert dot into single left status dot (lr-0aa7b6)",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T16:31:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6570ed7f037d2387d568e4d730ebbd09a06ef08e",
          "body": "…path-mismatch\n\nfix(worktree): resolve actual registered path before removing a worktree (lr-76fbc3)",
          "is_bot": true,
          "headline": "Merge pull request #365 from clagentic/fix/lr-76fbc3-worktree-remove-…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-18T16:18:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7e62945efb42d1c045f2dda0e29af4b9ad8584b5",
          "body": "…alone (lr-76fbc3)\n\nPEACHES flagged PR #365: resolveWorktreePath() matched on basename alone,\nso two worktrees with the same leaf dirName under different parents\n(e.g. ./feat and ../sibling/feat) would silently resolve to whichever\nentry sorted first in `git worktree list --porcelain`, removing the\n\n[…]\ndParent, so it can never point at another\nparent's tree.\n\nAdds a regression test with two same-basename worktrees under\ndifferent parents asserting only the targeted parent's worktree is\never removed.",
          "is_bot": true,
          "headline": "fix(worktree): bind path resolution to parent identity, not basename …",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T16:11:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6ff6c68ae29441c41f8dc784b111576a36da831f",
          "body": "… toast duration\n\n- worktree-remove-path-mismatch-lr-76fbc3.test.js: reproduces the\n  outside-parent-dir worktree removal that previously failed with\n  \"not a valid working tree\" (variant B), a baseline in-parent-dir\n  case (unaffected by the fix), and confirms a genuine remove failure\n  still surfa\n[…]\n check (matching\n  the existing diagnostics-toast-*-lr-* convention, since utils.js\n  has no DOM harness in this suite) asserting showToast's duration\n  logic special-cases \"error\" the same as \"warn\".",
          "is_bot": true,
          "headline": "test(worktree): add regression coverage for lr-76fbc3 path mismatch +…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T16:04:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "747075e337ef1f77ff7b84155d3f1d65e8a37a8f",
          "body": "…gs (lr-76fbc3)\n\nshowToast() dismissed \"error\" level toasts after 1500ms -- the same\nshort window as a plain success toast. That made the worktree-remove\nfailure toast (\"...is not a valid worktree\") dismiss before an operator\ncould read the actual error, which is why the underlying path-resolution\nbug this task fixes was so hard to diagnose from the UI. Error toasts now\nget the same 5000ms window as warnings; plain success/info toasts are\nunchanged.",
          "is_bot": true,
          "headline": "fix(ui): give error-level toasts the same readable duration as warnin…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T16:04:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6f272da78553983081039a6cb7cdbf6a7890ce5c",
          "body": "…ree (lr-76fbc3)\n\nremoveWorktree() reconstructed the target path as path.join(parentPath,\ndirName), which is only correct when the worktree lives directly inside\nthe parent project directory. A worktree registered elsewhere on disk\n(e.g. `git worktree add ../sibling -b x` run outside the app and lat\n[…]\n-porcelain` to resolve\nthe actual registered path before calling `git worktree remove`, falling\nback to the naive join only when no match exists (so a genuine failure\nstill surfaces git's real error).",
          "is_bot": true,
          "headline": "fix(worktree): resolve actual registered path before removing a workt…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T16:04:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "79bea25eb8d2eacec4de98ec6574538e3909a027",
          "body": "…ransient-401\n\nfix(app-connection): re-verify before terminal auth wall on wake reconnect (lr-e5c1fe)",
          "is_bot": true,
          "headline": "Merge pull request #364 from clagentic/fix/lr-e5c1fe-wake-reconnect-t…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-18T15:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ae47f972bfc42fea5f15d0ff3bef7b6fddc6f5b1",
          "body": "…nnect (lr-e5c1fe)\n\nA tab woken from background could fire its first post-wake fetch before\ncookies were reattached, causing a single spurious 401 on /api/ws-ticket\nor /info to trigger the full-screen \"Session expired\" interstitial on a\nstill-valid session (\"Sign in again\" — a bare connect() re-run \n[…]\nvering both retry paths.\n\nTests: npm test — 1042/1046 passing; the 4 remaining failures are\npre-existing, unrelated sdk-bridge-context-window-warn.test.js cgroup-guard\nfailures untouched by this diff.",
          "is_bot": true,
          "headline": "fix(app-connection): re-verify before terminal auth wall on wake reco…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T15:40:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e13287a66c3424d67b776aa1f352d2b070ebda52",
          "body": "…-wire-npm-test-into-ci\n\nci(lr-ae85d5): run npm test as a real pre-merge gate via pull_request",
          "is_bot": true,
          "headline": "Merge pull request #363 from clagentic/fix/lr-ae85d5-boot-graph-guard…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-18T15:23:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9d4cbe26450d3a2dd12c9ea8dffddac487737384",
          "body": "…-a7b03e",
          "is_bot": true,
          "headline": "test(lr-768c9e): quarantine flaky ownership-claim case, tracked as lr…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T15:15:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1bbb9a3e1d18ac68605fa7a78e3b9eec7bb1646a",
          "body": "…-ae85d5)\n\nloadUsers() previously caught every read/parse error and silently\nreturned an empty user set (defaultData()). A missing file (ENOENT)\nlegitimately means \"no users yet\" and should still default cleanly,\nbut a JSON parse failure or a transient read error under full-suite\nresource contention\n[…]\nrelated (test/sdk-bridge-context-\nwindow-warn.test.js, tests 627/628/629/636), unaffected by this change\nand present identically in the pre-fix baseline log.\n\nCo-Authored-By: AMoS <amos@noreply.local>",
          "is_bot": true,
          "headline": "fix(users): distinguish ENOENT from corrupt/unreadable users.json (lr…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T15:15:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4abc252d9f4d7a5ed78d544a562f366efb6dc366",
          "body": "… (lr-ae85d5)\n\nAdd a fail-loud check that findUserById(adminId) returns the seeded\nadmin before driving handleConnection(). findUserById gates whether\ncanAccessSession() includes the test's unowned session in\nallSessions -- if that lookup silently fails, handleConnection()\ntakes the autoCreated bran\n[…]\not\nconfirmed by direct evidence. Left as test-only diagnostic hardening\nrather than speculatively changing production error-handling in\nlib/users.js without proof, per the CI-wiring PR's narrow scope.",
          "is_bot": true,
          "headline": "test(lr-768c9e): assert findUserById resolves before handleConnection…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T15:15:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6d754164cc8347e4919ae60b3c5653e044603399",
          "body": "…5d5)\n\nlib/project-connection.js requires ../lib/lite-detect, which\ndestructures CLAGENTIC_HOME/REAL_HOME from ../lib/config at\nmodule-load time (lib/lite-detect.js:10) -- the same\nfrozen-at-first-require pattern as USERS_FILE in lib/users.js. This\nmodule was missing from REQUIRE_CACHE_MODULES, so o\n[…]\nS_FILE resolves under this\ntest's tmpHome, so any future instance of this class of staleness\nsurfaces immediately with a clear diagnostic instead of the confusing\ndownstream \"ownerId is null\" symptom.",
          "is_bot": true,
          "headline": "fix(test): bust ../lib/lite-detect require cache in lr-768c9e (lr-ae8…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T15:15:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "73b01129124366663649585fbbf049726dc7b3b4",
          "body": "lr-e31b's runNextIteration() test ran startLoop() against a bare\nmkdtempSync() dir with no .git ancestor. startLoop() shells\n`git rev-parse HEAD` and bails via loop_error before calling\nrunNextIteration() when that fails -- deterministic on a real CI\nrunner, but silently masked on hosts where /tmp is itself inside an\nambient git work tree. git-init the temp cwd with a single commit so\nthe test's git context matches a real project checkout regardless of\nhost.",
          "is_bot": true,
          "headline": "fix(test): git-init temp cwd so startLoop() sees a real HEAD (lr-ae85d5)",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T15:15:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "60bfc2c388f463ec2aadbbaef852eb00744d9ce3",
          "body": "NAOMI's merge_requirements name pr-checks.yml (ci_pass) and tests_pass as\ngates, but until now nothing in CI ran npm test -- esm-import-check.test.js\n(lr-5e24), boot-smoke-lr-1a5f, and app-boot-esm-graph-load-lr-4c58ae only\nran locally on the honor system before a PR was opened. Adds a separate\ntest job on the plain pull_request trigger (no secrets, unlike the\nexisting checks job's pull_request_target) so npm ci && npm test is safe\nto run against untrusted fork code.",
          "is_bot": true,
          "headline": "ci(lr-ae85d5): run npm test as a real pre-merge gate via pull_request",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-18T15:15:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b1d375ec47ab71e11f1e3d4e2e36d94fdfa2477b",
          "body": null,
          "is_bot": true,
          "headline": "chore: update promotable beta list [skip ci]",
          "author_name": "clagentic-release-bot[bot]",
          "author_login": "clagentic-release-bot[bot]",
          "committed_at": "2026-07-17T20:18:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4669ffc3ce29de647a1cd498f9d78e0283459150",
          "body": null,
          "is_bot": false,
          "headline": "Release 1.8.0-beta.1",
          "author_name": "semantic-release-bot",
          "author_login": "semantic-release-bot",
          "committed_at": "2026-07-17T20:17:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "78799e684c881154eb91ce85b731d3a82e080555",
          "body": "…cular-import-boot-halt\n\nfix(app-messages): break circular-import boot halt on handlers init (lr-4c58ae)",
          "is_bot": true,
          "headline": "Merge pull request #362 from clagentic/fix/lr-4c58ae-app-messages-cir…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-17T20:06:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "94bb90a1a5c397c6735ce20d1c23667fffd7ea1a",
          "body": "…lr-4c58ae)",
          "is_bot": true,
          "headline": "fix(app-messages): break circular-import boot halt on handlers init (…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T19:43:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb9f81cb56c032a27313e42b029f4fe34ce5c6aa",
          "body": "…cho-cookie-auth\n\nfix(server): echo offered ws subprotocol on cookie-authed upgrades (lr-4c58ae)",
          "is_bot": true,
          "headline": "Merge pull request #361 from clagentic/fix/lr-4c58ae-ws-subprotocol-e…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-17T18:59:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6fb46126d44473f49fa9e84111f77a9d57ae7013",
          "body": "extractWsTicketFromHeader() now runs unconditionally (pure parse, no\nside effect) so req._clayAcceptedProtocol can be set on the\ncookie-authed echo path too. Update the two source-text assertions\nthat pinned the old shape to instead verify the invariant they\nactually protect: auth.consumeWsTicket() (the validating call) still\nonly fires when the cookie path failed, and the accepted-protocol\nmarker still only ever echoes the client-offered value.",
          "is_bot": true,
          "headline": "test(server): update lr-de5fcb source-shape assertions for lr-4c58ae",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T18:41:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0792a8cabc953ce0feb949cda7f7ef1a6e4b2370",
          "body": "…r-4c58ae)\n\nlr-de5fcb (PR #358) made app-connection.js always fetch a ws-ticket and\nalways offer it as a Sec-WebSocket-Protocol subprotocol, including on\ndesktop (cookie-authed). The upgrade handler only parsed the offered\nticket inside the !wsCookieUser branch, so req._clayAcceptedProtocol was\nneve\n[…]\nthe cookie path the\noffered value is echoed as-is but never passed to consumeWsTicket -\nthe cookie already authenticated the request, so consuming would\nneedlessly burn the client's single-use ticket.",
          "is_bot": true,
          "headline": "fix(server): echo offered ws subprotocol on cookie-authed upgrades (l…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T18:33:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4243839901fe7afb44778dcd69471c55ad2028d8",
          "body": "…ore-auth-gate\n\nfix(server): serve public app-shell assets ahead of the project auth gate (lr-2895ea)",
          "is_bot": true,
          "headline": "Merge pull request #360 from clagentic/fix/lr-2895ea-shell-assets-bef…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-17T17:56:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26f71e63cf95713a8e6b7b774c58ca3944cd12c7",
          "body": "…th gate (lr-2895ea)\n\nSpawns a real daemon and asserts unauthenticated GET of app.js,\nstyle.css, and modules/app-connection.js returns 200 with the correct\nnon-HTML MIME, while the document navigation still returns the login\npage and /api/* + /ws upgrade both still 401.",
          "is_bot": true,
          "headline": "test(server): regression coverage for public shell assets ahead of au…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T17:47:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2d9dc3261b52f6723f914eed3adb816ecef9b7f7",
          "body": "…2895ea\n\napp.js and modules/app-connection.js are now real public shell assets\nserved ahead of the auth gate, so unauthenticated requests return 200\n+ the correct JS MIME type instead of the previous 401. Update the two\naffected assertions; nonexistent-asset and /api/* cases are unchanged.",
          "is_bot": true,
          "headline": "test(server): update lr-e33776 asset-auth-fallback assertions for lr-…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T17:47:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bf0a1868c7cda07564a404eaed3d22f5eeaea96f",
          "body": "…gate (lr-2895ea)\n\nMobile browsers withhold the SameSite=Lax session cookie on subresource\nrequests even on an authenticated top-level document navigation, so\napp.js, style.css, and /modules/*.js were 401ing unauthed for mobile\nclients — CSS never applied and the nosniff-rejected module never\nbooted\n[…]\n\nshell assets are public and identical for every user, so serve them\nvia serveStatic() before the auth gate instead of gating them.\n\nThe document navigation (/p/{slug}/), /api/*, and /ws remain gated.",
          "is_bot": true,
          "headline": "fix(server): serve public app-shell assets ahead of the project auth …",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T17:47:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1dc3ae4861b16813e90a1561318d75c9d1f1a9f4",
          "body": "…th-fallback\n\nfix(server): never serve login HTML for unauthed project-asset/API paths (lr-e33776)",
          "is_bot": true,
          "headline": "Merge pull request #359 from clagentic/fix/lr-e33776-project-asset-au…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-17T16:21:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8378201c954b7d58e8e535ff3f88e993e4f9b00f",
          "body": "…ths (lr-e33776)",
          "is_bot": true,
          "headline": "fix(server): never serve login HTML for unauthed project-asset/API pa…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T16:11:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "97cf902594cf0ab516970c239c1414a0a6ff8f35",
          "body": "…t-auth\n\nfix(ws-auth): non-cookie ticket fallback for mobile WS-upgrade auth (lr-de5fcb)",
          "is_bot": true,
          "headline": "Merge pull request #358 from clagentic/fix/lr-de5fcb-ws-upgrade-ticke…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-17T14:14:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "78d7d222bf888bab394a0a15d88d1e67612db68c",
          "body": "Functional tests against the real server-auth.js ticket store (mint,\nsingle-use consumption, cross-value isolation, TTL expiry) plus\nsource-text checks (following the pwa-stale-sw-reconnect-lr-e0ec47\nconvention for DOM/HTTP-upgrade-dependent files) covering: the upgrade\nhandler's cookie-primary/tick\n[…]\nubprotocol\necho, ticket extraction from Sec-WebSocket-Protocol only (never a query\nstring), debug-gated non-value logging, and the Surface-1\nunauthenticated-vs-unreachable branch in app-connection.js.",
          "is_bot": true,
          "headline": "test(auth): regression coverage for WS-upgrade ticket auth (lr-de5fcb)",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T14:06:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dd37297764929c39d319a3c3692090af17760084",
          "body": "…reachable (lr-de5fcb)\n\nSurface 2 (primary): connect() fetches a short-TTL ticket from\n/api/ws-ticket and offers it as a Sec-WebSocket-Protocol subprotocol before\nopening the socket, giving the upgrade a non-cookie credential path for\nmobile browsers that drop the cookie on the handshake. The WS URL\n[…]\nred\" state with\na manual sign-in action. Triggered by (a) a 401 on the ticket fetch, (b) an\nupgrade that never reaches onopen despite offering a ticket, and (c) a 401\non the /info reconnect preflight.",
          "is_bot": true,
          "headline": "fix(app-connection): fetch WS ticket before connect, split auth vs un…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T14:06:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "58d21ebf9601d58e86ea1944e7f51659d9c81321",
          "body": "…t (lr-de5fcb)\n\nWire the ws-ticket store into the /ws upgrade handler: the session cookie\nremains the primary auth path (desktop), falling back to a ticket offered\nvia Sec-WebSocket-Protocol when the cookie is absent (mobile). Echo the\naccepted subprotocol in the 101 handshake via WebSocketServer's\nhandleProtocols hook. Add GET /api/ws-ticket (requires the cookie) to mint\ntickets. Add a debug-gated rejected-upgrade log recording cookie/ticket\npresence (never values) for future diagnosability.",
          "is_bot": true,
          "headline": "feat(server): accept ticket fallback on WS upgrade, add /api/ws-ticke…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T14:06:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f2a624299e361282406be77b7ed9dede6d7dea08",
          "body": "The /ws upgrade authenticated only via the SameSite=Lax relay_auth_user\ncookie, which mobile browsers don't reliably attach to a script-initiated\nWebSocket handshake (MILLER, lr-de5fcb comment #1). Add a mint/consume\nticket store as a non-cookie fallback credential: opaque, userId-bound,\nsingle-use, 30s TTL.",
          "is_bot": true,
          "headline": "feat(auth): add short-TTL single-use WS-upgrade ticket store (lr-de5fcb)",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-17T14:06:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce0217a30b82030b51235f561121cba46cd7e854",
          "body": "…onnect\n\nfix(pwa): reconnect after stale SW/version mismatch (lr-e0ec47)",
          "is_bot": true,
          "headline": "Merge pull request #357 from clagentic/fix/lr-e0ec47-pwa-stale-sw-rec…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-16T23:40:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e1bcbc653b7877854bedfb5cd1939dcd8c923817",
          "body": "…ixes\n\nSource-text probes (matching the frontend-state-correlation-lr-fb49.test.js\nconvention, since this suite has no DOM/SW harness) covering:\n- notifications.js: reg.update() on register, visibilitychange, pageshow\n- command-palette.js: getPaletteVersion accessor\n- app-connection.js: /info-driven\n[…]\nges old caches and claims clients\n\n8/8 new tests pass; full suite has 3 pre-existing failures in\nsdk-bridge-context-window-warn.test.js unrelated to this change and\npresent on main before this branch.",
          "is_bot": true,
          "headline": "test(pwa-reconnect): regression coverage for lr-e0ec47 SW/reconnect f…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T23:32:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "93653bdd4c07331e68ec4987290038bce70bb84e",
          "body": "…-e0ec47)\n\nEven with the SW's reg.update() fix, a client can still be caught running\na pre-deploy bundle for a while (e.g. the update() call itself hasn't\nresolved yet, or the browser is between checks). scheduleReconnect's\nexisting /info preflight now also compares the server's currently-served\nver\n[…]\nretry a connection whose client code may no\nlonger match the server's message contract.\n\nThe streak resets on any successful (re)connect, and a single transient\n/info hiccup does not trigger a reload.",
          "is_bot": true,
          "headline": "fix(app-connection): reload on a sustained stale-version mismatch (lr…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T23:32:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ac5c4b4da096b3f2038e98b5dcc21f7fc925a9aa",
          "body": "Read-only accessor for the version cached from the WS 'info' handshake\nmessage (setPaletteVersion). Reused by the stale-bundle watchdog in\napp-connection.js instead of introducing a second client-side version\ncache.",
          "is_bot": true,
          "headline": "feat(command-palette): expose getPaletteVersion accessor (lr-e0ec47)",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T23:32:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a69958363b7e6fdf679d2d048ef6e4fb1cd1fb0",
          "body": "…ow (lr-e0ec47)\n\nPreviously install only called skipWaiting() without populating the new\nCACHE_NAME. On activate the old cache generation is deleted immediately,\nso between activate and the first successful network fetch the new cache\nis empty. A mobile client that goes offline in that window falls \n[…]\ne generation is never empty at\nactivate time. Best-effort: a failed pre-cache does not block\nskipWaiting — the fetch handler's cache-fallback still serves whatever\nthe previous cache generation holds.",
          "is_bot": true,
          "headline": "fix(sw): pre-cache app shell on install to close the empty-cache wind…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T23:32:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "438e7d083e370ced4e355f5b7815f7591f59e80a",
          "body": "sw.js is served no-cache (server.js serveStatic), so reg.update() always\nre-fetches it and picks up a post-deploy change. Without an explicit\nupdate() call the browser only re-checks sw.js on its own heuristic\nschedule, so a foregrounded mobile PWA that never navigates can hold a\npre-deploy SW+cache\n[…]\n to server\" overlay after a deploy.\n\nAlso re-checks on visibilitychange and pageshow so a backgrounded-then-\nresumed PWA re-validates promptly instead of waiting on the browser's\nown update heuristic.",
          "is_bot": true,
          "headline": "fix(sw): call reg.update() on register and on foreground (lr-e0ec47)",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T23:32:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a7e71e821dd87adaa5120766421ecc59a0b07150",
          "body": "…istry\n\nmerge(lr-4e49): app-messages.js switch -> handler registry (part 2) (#356)\n\nPEACHES clean (comment 4996606763), BOBBIE clean (comment 4996649364), both verified at head_sha a2064873a0ee62f07f9d70d670e96f2156786796.\n\n--skip-commit-check used for pre-existing base-sync merge commit 25a68af1d73\n[…]\n2a2decdd0e99e1af (tree 39aec0f0...), verified byte-identical (git diff --stat: empty) to main's own 52d716b copy of the same PR #355 merge -- same pattern as PR #355. No new or non-conformant content.",
          "is_bot": true,
          "headline": "Merge pull request #356 from clagentic/chore/lr-4e49-app-messages-reg…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-16T21:16:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a2064873a0ee62f07f9d70d670e96f2156786796",
          "body": "…lay.js (lr-4e49)",
          "is_bot": true,
          "headline": "docs(module-map): describe app-messages.js registry + app-history-rep…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T21:01:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6588423150ff642e69ccc02179c972b07ee952fc",
          "body": "…-4e49)",
          "is_bot": true,
          "headline": "test(app-messages): update source-text probes for registry syntax (lr…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T21:00:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "797d9c6ae63f23003d564304a73c8daf683aa91c",
          "body": "… (lr-4e49)",
          "is_bot": true,
          "headline": "test(app-messages): assert registry covers full pre-refactor case set…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T21:00:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aabd71004570e4197d190e0cfcfc9e37dae46f1b",
          "body": "…lr-4e49)",
          "is_bot": true,
          "headline": "refactor(app-messages): convert 185-case switch to handler registry (…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T21:00:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "44a6d7faa5a2daa09037540bb6ff1e9896619ed3",
          "body": "…handlers (lr-4e49)",
          "is_bot": true,
          "headline": "refactor(app-messages): filebrowser/server-settings self-register WS …",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T21:00:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "21ad8879409f2c437c718cd7be77f8f41d8ef0c2",
          "body": "…js (lr-4e49)",
          "is_bot": true,
          "headline": "refactor(app-messages): extract history replay to app-history-replay.…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T21:00:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "52d716b68ef498385948f73e53d831f832728f31",
          "body": "refactor(cli): split bin/cli.js into lib/cli/ modules (lr-4e49)",
          "is_bot": true,
          "headline": "Merge pull request #355 from clagentic/chore/lr-4e49-split-cli-part1",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-16T20:40:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25a68af1d7338838f82d04ed2a2decdd0e99e1af",
          "body": "refactor(cli): split bin/cli.js into lib/cli/ modules (lr-4e49)",
          "is_bot": true,
          "headline": "Merge pull request #355 from clagentic/chore/lr-4e49-split-cli-part1",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T20:40:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5edbce4ebda9b68c761c756eb8987feda3060b93",
          "body": "Completes the lr-4e49 Part 1 split: bin/cli.js (2855 lines) drops to arg\nparsing, --shutdown/--restart/--add/--remove/--list dispatch, and the main\nIIFE, wired to the new lib/cli/{tui,net-detect,daemon-launch,menus,\nipc-subcommands}.js modules -- down from 2855 to under 450 lines.\n\nAlso folds in lr-\n[…]\nw diff.\n\nTests: npm test -> 998 pass / 3 fail, matching the pre-existing\nenv-dependent failures in sdk-bridge-context-window-warn.test.js (verified\nidentical failure count on main before this branch).",
          "is_bot": true,
          "headline": "refactor(cli): trim bin/cli.js to arg parsing + main entry (lr-4e49)",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T20:25:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "977981552d2826653c69e70a9471e5dc9b40264f",
          "body": "…mands.js (lr-4e49)\n\n--shutdown/--restart/--add/--remove/--list are simple one-shot handlers that\ntalk to the daemon over the Unix socket and exit directly -- pulling them\nout of bin/cli.js's arg-parse block keeps that file to parsing + dispatch\nand helps it clear the ~400-line target for this split. No behavior change.",
          "is_bot": true,
          "headline": "refactor(cli): extract one-shot IPC subcommands to lib/cli/ipc-subcom…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T20:25:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1e68b0e04c5a296f240036c284cebec74859e358",
          "body": "Relocates the first-run setup wizard, the restore-projects prompt, and the\nmain/settings management menus out of bin/cli.js. No behavior change,\nincluding the pre-existing toClayStudioUrl() latent bug (undefined\nidentifier, only reachable when config.builtinCert is set) -- out of scope\nfor this behavior-preserving split.",
          "is_bot": true,
          "headline": "refactor(cli): extract interactive menus to lib/cli/menus.js (lr-4e49)",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T20:24:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "834577c46397e2cd7e0dda71b450ec949a554901",
          "body": "…lr-4e49)\n\nRelocates forkDaemon/devMode, the plain and TLS restart paths, the\ndaemon-liveness watcher, and crash-recovery/backoff out of bin/cli.js.\nCLI flags these functions need (port, useHttps, cliPin, noRestart, ...) are\nnow passed explicitly via a cliOpts bundle and a small setDaemonWatcherOpts/\ngetCliOpts pair, since arg parsing stays in bin/cli.js. No behavior change.",
          "is_bot": true,
          "headline": "refactor(cli): extract daemon lifecycle to lib/cli/daemon-launch.js (…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T20:24:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ff299ab2bb97476f03a693146aa01b9c1800e60",
          "body": "…e49)\n\nFirst mechanical split of bin/cli.js's six concerns (lr-4e49 Part 1):\nANSI color helpers, the startup logo, and the interactive prompt widgets\n(promptToggle/Pin/Text/Select/MultiSelect). Pure functions + callbacks with\nno shared mutable state beyond the fixed isBasicTerm flag -- relocated\nverbatim, no behavior change.",
          "is_bot": true,
          "headline": "refactor(cli): extract terminal UI primitives to lib/cli/tui.js (lr-4…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T20:24:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f7aa715fc2f0be4969e57a4b90bbdf4ddd3bec90",
          "body": "…it-log\n\nfeat(server-settings): audit-log custom-emoji upload/delete on success and failure (lr-fc71)",
          "is_bot": true,
          "headline": "Merge pull request #354 from clagentic/chore/lr-fc71-custom-emoji-aud…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-16T18:39:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7516d022be33ae551c9d01c8bb39b7b44130b61a",
          "body": "…it-log\n\nfeat(server-settings): audit-log custom-emoji upload/delete on success and failure (lr-fc71)",
          "is_bot": true,
          "headline": "Merge pull request #354 from clagentic/chore/lr-fc71-custom-emoji-aud…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T18:39:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d290cae233e4658a0fdf2c99059b719bb30a2fec",
          "body": "…s and failure (lr-fc71)\n\nMILLER bounce off PR #303 (emoji-picker silent-failure diagnosis): custom-\nemoji uploads left zero runtime trace in audit.log, so a silent no-op\nrequired a live browser repro to diagnose. Both POST and DELETE\n/api/custom-emoji/:slug now call audit.log(\"custom_emoji.upload\" \n[…]\nver-admin.js.\n\nAdds a regression test exercising lib/audit.js directly against a temp\nCLAGENTIC_HOME, following the established per-test require-cache-bust\npattern (session-lifecycle-lr-e0de.test.js).",
          "is_bot": true,
          "headline": "feat(server-settings): audit-log custom-emoji upload/delete on succes…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T18:32:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9dbb79542bbdc222f30a2757a3bc05b54a2f1740",
          "body": "…icate-utils\n\nfix(security): consolidate escapeHtml onto canonical helper, close single-quote gap (lr-2f75)",
          "is_bot": true,
          "headline": "Merge pull request #353 from clagentic/chore/lr-2f75-consolidate-dupl…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-16T18:19:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7c37828584f1d67884f74c71a10c2d0c1625f98a",
          "body": "…red helper (lr-2f75)\n\nfilebrowser.js (formatTimeAgo), app-home-hub.js (formatRelativeTime),\ncommand-palette.js (formatRelativeDate), and sidebar-sessions.js\n(relativeTime) each reimplemented the same \"Xm ago / Xh ago / Xd ago\"\nlogic with minor formatting drift. Extracted to\nlib/public/modules/relative-time.js, re-exported through the utils.js\nbarrel alongside escapeHtml, and updated all four call sites.",
          "is_bot": true,
          "headline": "refactor(frontend): consolidate relative-time formatters into one sha…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T18:09:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6afb22ce71475865dd6c049ef446be2cf6008c6f",
          "body": "…ngle-quote gap (lr-2f75)\n\nscheduler-history.js, server-settings.js, and project-settings.js each\ncarried a local escapeHtml reimplementation that encoded &, <, >, and \"\nbut not ' — an XSS-consistency risk in single-quoted attribute contexts.\ncontext-sources.js had a DOM-based textContent/innerHTML \n[…]\nrt the canonical escapeHtml from\nlib/public/modules/escape-html.js (via the utils.js barrel), which\nalready escapes single quotes to &#39; and is covered by\ntest/xss-escape.test.js. Dovetails lr-cc85.",
          "is_bot": true,
          "headline": "fix(security): consolidate escapeHtml onto canonical helper, close si…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T18:09:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2e46b680b4237cc94f1726188164fa3800057a78",
          "body": "…spacing\n\nfix(brand): add space in Clagentic:Console wordmark (lr-a924)",
          "is_bot": true,
          "headline": "Merge pull request #352 from clagentic/fix/lr-a924-clagentic-console-…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-16T17:53:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb7ff4b6698cf35793dd9b8ccfd931751026f023",
          "body": "…Console' (lr-a924)\n\nRepo brand rule requires 'Clagentic: Console' (capital C, colon,\nspace, capital C) as the product name. 56 user-facing occurrences of\nthe no-space wordmark 'Clagentic:Console' were found across 15 files\n(page titles, HTML labels, notification/toast copy, PWA manifest,\nservice wo\n[…]\n pre-existing failures in\ntest/sdk-bridge-context-window-warn.test.js (env-dependent cgroup\nmemory guard flake, unrelated to this change, called out in the\ndispatch as a known baseline issue on main).",
          "is_bot": true,
          "headline": "fix(brand): add space in 'Clagentic:Console' wordmark to 'Clagentic: …",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T17:46:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7b5ac39e23d6fd0c4215485df8df238bd0a51a28",
          "body": "…-tests\n\ntest(security): add 401 regression tests for sibling settings routes (lr-30a5)",
          "is_bot": true,
          "headline": "Merge pull request #351 from clagentic/test/lr-30a5-sibling-route-401…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-16T17:34:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "508e6a0880abd0449de7c720b01b447f4f98b089",
          "body": "…utes (lr-30a5)\n\nPEACHES re-review of PR#213 (lr-d857) found the B2 test rewrite only\ncovered enable-multiuser/profile/avatar/skills, missing regression\ncoverage for chat-layout, theme-mode, theme-brand, tool-palettes PUT,\nand auto-continue. Per amos.code-craft.4 each 401 gate needs a test\nthat fail\n[…]\n is reverted.\n\nNote: /api/user/auto-continue is a GET route in server-settings.js,\nnot PUT as originally described in the task — test targets the real\nroute to keep the regression coverage meaningful.",
          "is_bot": true,
          "headline": "test(security): add 401 regression tests for five sibling settings ro…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T17:22:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d3e24ad660141beca6a17b8d8234d55986c8e875",
          "body": "…-left-offset\n\nfix(diagnostics): reset left/bottom on diagnostic toast to stop right-edge clipping (lr-56fb36)",
          "is_bot": true,
          "headline": "Merge pull request #350 from clagentic/fix/lr-56fb36-diagnostic-toast…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-16T13:16:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a03f19f939e22e1bc3d4b2fdddff7d7d5f034f9e",
          "body": "…-edge clipping (lr-56fb36)\n\n.toast-diagnostic already overrode position and transform from the base\n.toast rule (base.css), but never reset left (50%) or bottom (80px) --\nthose two properties kept leaking through from the old center-bottom\nsingle-toast pattern, offsetting every diagnostic toast awa\n[…]\nstrap-guard.test.js (CLAGENTIC_HOME env bootstrap\nguard) and 3 in test/sdk-bridge-context-window-warn.test.js (cgroup memory\nheadroom calculation) -- neither touches CSS or the diagnostics toast path.",
          "is_bot": true,
          "headline": "fix(diagnostics): reset left/bottom on diagnostic toast to stop right…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T13:06:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "03006118237337a20f86e4ffab8172986432c796",
          "body": null,
          "is_bot": true,
          "headline": "chore: update promotable beta list [skip ci]",
          "author_name": "clagentic-release-bot[bot]",
          "author_login": "clagentic-release-bot[bot]",
          "committed_at": "2026-07-16T12:32:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c9d70891483d21fe59b0e73e3bed2fad1a443cb9",
          "body": null,
          "is_bot": false,
          "headline": "Release 1.7.1-beta.1",
          "author_name": "semantic-release-bot",
          "author_login": "semantic-release-bot",
          "committed_at": "2026-07-16T12:31:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ee2ca7ddee44ef2c81c21ed3d2362dc3f81cb71",
          "body": "…nloaded-sessions\n\nfix(palette): scan unloaded session history from disk for BM25 search (lr-a3e175)",
          "is_bot": true,
          "headline": "Merge pull request #349 from clagentic/fix/lr-a3e175-palette-search-u…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-16T12:04:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "40ed1d45dcf40b8cafb85ea68a7a21d47ec53d3a",
          "body": "…e175)\n\nCovers: palette search finds a needle in a session forced into the\nLRU-evicted/unloaded state (empty history array, _historyLoaded: false),\nand confirms the search does not mutate _historyLoaded/session.history as\na side effect. Also covers the back-compat fallback path when no\ngetHistory callback is supplied. Drives real production code from\nlib/sessions.js and lib/session-search.js, following the\nsession-search-streaming-lr-2ea2a7.test.js pattern.",
          "is_bot": true,
          "headline": "test(palette): regression coverage for unloaded-session search (lr-a3…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T11:57:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ab578b64d6e3a6e63cab256ec1d740a9264c725f",
          "body": "… (lr-a3e175)\n\n/api/palette/search iterated session.history directly with no\nloadSessionHistory() and no disk-backed read, so a session that was\nLRU-evicted or never opened since daemon start contributed zero/partial\nhits to BM25 palette search.\n\nsession-search.js's sessionHistoryToDocs()/searchPale\n[…]\nupplies sm.readSessionHistoryFromDisk per\nsession, mirroring the lr-2ea2a7 streaming-disk precedent used by\nsm.searchSessions/searchSessionContent — no loadSessionHistory() call, no\nheap/LRU mutation.",
          "is_bot": true,
          "headline": "fix(palette): scan unloaded session history from disk for BM25 search…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-16T11:57:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "87ff4c96206754e78c284a2a851db3ed511cf124",
          "body": "…noop\n\nfix(lr-fc2818): remove-worktree no-op discards onRemoveProject result",
          "is_bot": true,
          "headline": "Merge pull request #348 from clagentic/fix/lr-fc2818-remove-worktree-…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-15T23:17:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ffb30d24b192ca7d7a97b28b2f52b5f68cc27b5e",
          "body": null,
          "is_bot": true,
          "headline": "lr-fc2818: regression test for remove_project result propagation",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-15T23:07:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a4efbeda613e5eab2a367f7a6ad1e8420f8f27c0",
          "body": "…d of a hardcoded ok:true",
          "is_bot": true,
          "headline": "lr-fc2818: forward onRemoveProject's real result to the client instea…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-15T23:07:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "863c81dc83653241c36958ce6ffcb7c8a4268e38",
          "body": "…n worktree parent is missing",
          "is_bot": true,
          "headline": "lr-fc2818: daemon onRemoveProject errors instead of false-success whe…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-15T23:07:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b74edb23cbc6cdf90319c61fa70d368359d090c0",
          "body": "fix(lr-d4413a): stop beta release job from clobbering main's version basis",
          "is_bot": true,
          "headline": "Merge pull request #347 from clagentic/fix/lr-d4413a-beta-release-no-op",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-15T20:34:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0732962bae25be4e875491fd5108bb2046e877c1",
          "body": "fix(lr-d4413a): stop beta release job from clobbering main's version basis",
          "is_bot": true,
          "headline": "Merge pull request #347 from clagentic/fix/lr-d4413a-beta-release-no-op",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-15T20:34:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "055d6c2d006559075e89201db1b5a4837a0dfa43",
          "body": null,
          "is_bot": true,
          "headline": "lr-d4413a: stop beta job from clobbering main's version basis",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-15T20:28:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "187b60ebc9581fe801c5aac2a4bc9dda1052af5d",
          "body": null,
          "is_bot": true,
          "headline": "Merge remote-tracking branch 'origin/release'",
          "author_name": "clagentic-release-bot[bot]",
          "author_login": "clagentic-release-bot[bot]",
          "committed_at": "2026-07-15T19:47:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "31f2dd857a2ea48087884cdcf9055725131db840",
          "body": "…-tarball-parse\n\nfix(lr-0d45): robust tarball-filename capture in install:local-test",
          "is_bot": true,
          "headline": "Merge pull request #346 from clagentic/fix/lr-0d45-install-local-test…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-15T17:32:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d34f3f00dcd609aeddeeb115ec15e1d4ebb40db5",
          "body": "$(npm pack) captured npm's multi-line human notices, not just the\ntarball filename, causing npm install -g to fail EINVALIDPACKAGENAME.\nThis ran during PR #345's post_merge_steps and failed loud, exactly as\nthe on_failure:fail hardening intended, but the install must actually\nsucceed.\n\nReplaces the \n[…]\ne same stream.\n\nVerified end-to-end: npm run install:local-test succeeds, and npm run\nverify:installed-build passes, confirming the installed build-sha.json\nmatches the working tree's actual HEAD SHA.",
          "is_bot": true,
          "headline": "lr-0d45: fix install:local-test tarball-filename capture bug",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-15T17:26:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a86809985ccb9bf66328a3ded7b19d1320a216b5",
          "body": "…-hardening\n\nfix(lr-0d45): migrate post_merge_steps to .clagentic/loadout/config.yaml and harden install verification",
          "is_bot": true,
          "headline": "Merge pull request #345 from clagentic/fix/lr-0d45-loadout-post-merge…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-15T17:14:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3bba8e48da22558812add1e353112e0ff8c7e303",
          "body": "loadout-merge never reads .crew/naomi.yaml -- it reads\n.clagentic/loadout/config.yaml exclusively. Leaving a post_merge_steps\nkey here was a second, unread source of truth that could be mistaken\nfor live config. The equivalent (now hardened) steps live at\n.clagentic/loadout/config.yaml merge.post_merge_steps.",
          "is_bot": true,
          "headline": "lr-0d45: remove dead post_merge_steps from .crew/naomi.yaml",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-15T17:07:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7fbb0137ac5f3adf6c2909d5469d70ca3e0a3db9",
          "body": "…onfig)\n\nloadout-merge (the only reachable merge entrypoint for this repo since\ncrew_merge.py's GitHub path was deprecated, lr-d9729d) reads\npost_merge_steps and gate declarations exclusively from\n.clagentic/loadout/config.yaml -- this repo had no such file, so the\nhardened install/verify steps had \n[…]\nIE required reviewers, NAOMI merge authority) in the\ntask brief.\n\nWidens .crew/amos.yaml scope.allowed_paths to include .clagentic/**\nsince this file did not previously exist under any declared scope.",
          "is_bot": true,
          "headline": "lr-0d45: initialize .clagentic/loadout/config.yaml (live merge-gate c…",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-15T17:07:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "91e3d6154411c76764cb017e2532b9541ecad5d6",
          "body": "lib/build-sha.json is written by scripts/write-build-sha.js at npm's\nprepack time -- never hand-authored, never committed. It still ships\nin published tarballs because it's written before npm pack runs, not\nbecause it's git-tracked.",
          "is_bot": true,
          "headline": "lr-0d45: gitignore the generated build-sha.json pack artifact",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-15T17:07:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4c7d970956fad62cf2588a34d19bcf00484b51f1",
          "body": "Adds scripts/write-build-sha.js (npm prepack hook) which embeds the\ncurrent git HEAD SHA into lib/build-sha.json so a packed tarball\ncarries a build-identity signal. Adds scripts/verify-installed-build.js\nwhich compares the globally-installed package's embedded SHA against\nthis tree's HEAD, exiting non-zero on mismatch. Neither script is wired\ninto any merge gate yet -- that follows in .clagentic/loadout/config.yaml.",
          "is_bot": true,
          "headline": "lr-0d45: embed build SHA + verify-installed-build post-merge check",
          "author_name": "clagentic-builder[bot]",
          "author_login": "clagentic-builder[bot]",
          "committed_at": "2026-07-15T17:06:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a6eb238f9a619dc9547df26d72ae62d78837992e",
          "body": "…gent-orphan\n\nfix(lr-f36626): stop idle reaper from orphaning live background subagents",
          "is_bot": true,
          "headline": "Merge pull request #344 from clagentic/fix/lr-f36626-idle-reaper-suba…",
          "author_name": "clagentic-merger[bot]",
          "author_login": "clagentic-merger[bot]",
          "committed_at": "2026-07-15T15:34:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 45,
      "commits_last_year": 2650,
      "latest_release_at": "2026-07-17T20:17:47Z",
      "latest_release_tag": "v1.8.0-beta.1",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 24,
      "days_since_latest_release": 5,
      "mean_days_between_releases": 2.5
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 50,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@clagentic/console",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "claude",
            "claude-code",
            "claude-agent-sdk",
            "codex",
            "codex-cli",
            "openai",
            "self-hosted",
            "multi-user",
            "team",
            "workspace",
            "ai-agent",
            "ai-coding-agent",
            "clagentic",
            "cron",
            "mobile",
            "pwa",
            "web-ui",
            "browser"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@clagentic/console",
          "is_deprecated": false,
          "latest_version": "1.7.0",
          "repository_url": "https://github.com/clagentic/clagentic-console",
          "versions_count": 46,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 2243,
          "first_published_at": "2026-05-13T12:48:30.417000Z",
          "latest_published_at": "2026-07-14T20:53:17.092000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 8
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 3,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 5
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": true,
      "has_dockerfile": false,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 103115,
      "source_files_sampled": 288,
      "oversized_source_files": 14,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@anthropic-ai/claude-agent-sdk",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.3.173"
        },
        {
          "name": "@anthropic-ai/sdk",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.104.1"
        },
        {
          "name": "@lydell/node-pty",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.2.0-beta.3"
        },
        {
          "name": "@openai/codex",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.124.0"
        },
        {
          "name": "nodemailer",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^6.10.1"
        },
        {
          "name": "qrcode-terminal",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.12.0"
        },
        {
          "name": "web-push",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.6.7"
        },
        {
          "name": "ws",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.18.0"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 361,
        "open_issues": 5,
        "closed_ratio": 0.167,
        "closed_issues": 1,
        "closed_unmerged_prs": 3
      },
      "bus_factor": 1,
      "bot_contributors": 4,
      "top_contributors": [
        {
          "type": "User",
          "login": "chadbyte",
          "commits": 1166,
          "avatar_url": "https://avatars.githubusercontent.com/u/236304852?v=4"
        },
        {
          "type": "User",
          "login": "akuehner",
          "commits": 652,
          "avatar_url": "https://avatars.githubusercontent.com/u/10177887?v=4"
        },
        {
          "type": "User",
          "login": "semantic-release-bot",
          "commits": 348,
          "avatar_url": "https://avatars.githubusercontent.com/u/32174276?v=4"
        },
        {
          "type": "User",
          "login": "PancakeZik",
          "commits": 13,
          "avatar_url": "https://avatars.githubusercontent.com/u/20574058?v=4"
        },
        {
          "type": "User",
          "login": "leiyangyou",
          "commits": 10,
          "avatar_url": "https://avatars.githubusercontent.com/u/104397?v=4"
        },
        {
          "type": "User",
          "login": "materemias",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/529994?v=4"
        },
        {
          "type": "User",
          "login": "seidnerj",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/4147381?v=4"
        },
        {
          "type": "User",
          "login": "qwaguet",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/128394937?v=4"
        },
        {
          "type": "User",
          "login": "DotDebian",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/20359522?v=4"
        },
        {
          "type": "User",
          "login": "colinmadere",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/601220?v=4"
        }
      ],
      "contributors_sampled": 16,
      "top_contributor_share": 0.529
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "pr-checks.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 1,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/1 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 5 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 0,
            "reason": "dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 2,
            "reason": "dependency not pinned by hash detected -- score normalized to 2",
            "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": "51 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "1cddcc115ad0b2a115d91b80e2b4abe805738052",
        "ran_at": "2026-07-23T03:52:07Z",
        "aggregate_score": 2.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-22T21:14:38Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-22T21:14:01Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 221,
          "created_at": "2026-06-11T09:28:49Z",
          "last_comment_at": "2026-06-11T17:15:38Z",
          "last_comment_author": "clagentic-triage"
        },
        {
          "number": 222,
          "created_at": "2026-06-11T09:30:32Z",
          "last_comment_at": "2026-06-11T17:15:37Z",
          "last_comment_author": "clagentic-triage"
        },
        {
          "number": 314,
          "created_at": "2026-07-07T20:05:02Z",
          "last_comment_at": "2026-07-10T19:09:57Z",
          "last_comment_author": "clagentic-triage"
        },
        {
          "number": 315,
          "created_at": "2026-07-07T21:37:46Z",
          "last_comment_at": "2026-07-10T19:21:13Z",
          "last_comment_author": "akuehner"
        },
        {
          "number": 328,
          "created_at": "2026-07-10T22:50:49Z",
          "last_comment_at": "2026-07-14T19:46:08Z",
          "last_comment_author": "clagentic-triage"
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/clagentic/clagentic-console",
    "host": "github.com",
    "name": "clagentic-console",
    "owner": "clagentic"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 57,
      "inputs": {
        "security": 22,
        "vitality": 83,
        "community": 40,
        "governance": 54,
        "engineering": 77
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 83,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 71,
            "inputs": {
              "commits_last_year": 2650,
              "human_commit_share": 0.02,
              "days_since_last_push": 0,
              "active_weeks_last_year": 24
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "24/52 weeks with commits",
                "points": 16.6,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 24
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "2650 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 2650
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 45,
              "latest_release_tag": "v1.8.0-beta.1",
              "releases_from_tags": false,
              "days_since_latest_release": 5,
              "mean_days_between_releases": 2.5
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "45 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 45
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~2.5 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 2.5
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 40,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 5,
            "inputs": {
              "forks": 0,
              "stars": 3,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "3 stars",
                "points": 4.9,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 56,
            "inputs": {
              "packages": [
                "@clagentic/console"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 2243
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "2,243 downloads/month across npm",
                "points": 44.7,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 2243,
                      "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": "moderate",
        "name": "Sustainability & Governance",
        "value": 54,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "at_risk",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 43,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 16,
              "top_contributor_share": 0.529
            },
            "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 53% of commits",
                "points": 10.6,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 53
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "16 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 16
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 5 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "at_risk",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 46,
            "inputs": {
              "merged_prs": 361,
              "open_issues": 5,
              "closed_issues": 1,
              "issue_closed_ratio": 0.167,
              "closed_unmerged_prs": 3
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "17% of issues closed",
                "points": 7.8,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 17
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "361/364 decided PRs merged",
                "points": 37.9,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 361,
                      "decided": 364
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/1 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 37,
            "inputs": {
              "followers": 0,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "clagentic",
              "public_repos": 7,
              "account_age_days": 89
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "0 followers of clagentic",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "clagentic"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "7 public repos, account ~0 yr old",
                "points": 7.1,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 7
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "@clagentic/console"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 8
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 8 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "46 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 46
                    }
                  }
                ],
                "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": "good",
        "name": "Engineering Quality",
        "value": 77,
        "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": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "topics": [
                "ai-tooling",
                "browser-ui",
                "claude-code",
                "developer-tools",
                "pwa",
                "self-hosted",
                "clagentic-tool"
              ],
              "has_wiki": false,
              "homepage": "https://clagentic.ai",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://clagentic.ai",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "7 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "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": "critical",
        "name": "Security",
        "value": 22,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 22,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 2.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 is not maximal on development and all release branches",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/1 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 5 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "dangerous workflow patterns detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 2",
                "points": 1,
                "status": "partial",
                "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": "51 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 8
            },
            "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": "at_risk",
        "name": "AI Readiness",
        "value": 32,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "critical",
            "name": "Agent context & guidance",
            "note": "Excluded from scoring (no data or not applicable): Legible commit history. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "legible_commit_history"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 25,
            "inputs": {
              "has_llms_txt": true,
              "legible_history_share": null,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": "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": "no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 34,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 2",
                "points": 2,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 52,
            "inputs": {
              "primary_language": "JavaScript",
              "largest_source_bytes": 103115,
              "source_files_sampled": 288,
              "oversized_source_files": 14
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "JavaScript without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "JavaScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "14/288 source files over 60KB",
                "points": 52.3,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 288,
                      "oversized": 14
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "critical",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 20,
            "inputs": {
              "example_dirs": [],
              "has_mcp_signal": true,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index npm:@clagentic/console@1.7.0; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-23T03:52:31.134749Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/c/clagentic/clagentic-console.svg",
  "full_name": "clagentic/clagentic-console",
  "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.